带有嵌套属性的Rails before_update回调 [英] Rails before_update callback with nested attributes
问题描述
我有两个模型(先叫A
和B
).
A
has_many
b
s和B
belongs_to
A
.
class A < ApplicationRecord
has_many :bs, dependent: :destroy, inverse_of: :a
accepts_nested_attributes_for :bs, reject_if: :all_blank, allow_destroy: true
validates_associated :bs
end
class B < ApplicationRecord
belongs_to :a, inverse_of: :bs
before_update :do_something, unless: Proc.new { |b| b.a.some_enum_value? if a }
def do_something
self.some_field = nil
end
end
除此之外, 由于此关系用于嵌套表格,因此仅当我更新属性表格 在更新 提前谢谢. 对于属于关联,可以使用 当您更新B时,哪个会更新 但是您可以自己滚动: I have two models (lets call then Other than that, Since this relation is used on a nested form, that How can I call Thanks in advance. For belongs to associations you can use the Which would update You can roll your own however:
这篇关于带有嵌套属性的Rails before_update回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!B
具有before_update
回调,如果 A
已设置some_enum_value
,则将some_field
设置为零.
B
时,才会调用B
中的before_update
.如果我仅更改值形式A
,则不会调用该回调.A
时如何调用B
的before_update
?touch
选项:class B < ApplicationRecord
belongs_to :a, inverse_of: :bs, touch: true
end
a.updated_at
.
但是,对于has_many
关系,此选项不存在,因为它可能会对性能造成潜在的灾难性影响(如果A的个数为1000或更多,则Bs.)class A < ApplicationRecord
has_many :bs, dependent: :destroy, inverse_of: :a
accepts_nested_attributes_for :bs, reject_if: :all_blank, allow_destroy: true
validates_associated :bs
after_update :cascade_update!
def cascade_update!
# http://api.rubyonrails.org/classes/ActiveRecord/Batches.html#method-i-find_each
bs.find_each(batch_size: 100) do |b|
b.update!(updated_at: Time.zone.now)
end
end
end
A
and B
).A
has_many
b
s and B
belongs_to
A
.class A < ApplicationRecord
has_many :bs, dependent: :destroy, inverse_of: :a
accepts_nested_attributes_for :bs, reject_if: :all_blank, allow_destroy: true
validates_associated :bs
end
class B < ApplicationRecord
belongs_to :a, inverse_of: :bs
before_update :do_something, unless: Proc.new { |b| b.a.some_enum_value? if a }
def do_something
self.some_field = nil
end
end
B
has a before_update
callback that sets some_field
to nil if A
has some_enum_value
set.before_update
from B
is only being called if I update a attribute form B
. If I only change a value form A
that callback is not called.B
's before_update
when A
is updated?touch
option:class B < ApplicationRecord
belongs_to :a, inverse_of: :bs, touch: true
end
a.updated_at
when you update B.
However this option does not exist for has_many
relations since it could have potentially disastrous performance consequences (If an A has 1000s or more Bs).class A < ApplicationRecord
has_many :bs, dependent: :destroy, inverse_of: :a
accepts_nested_attributes_for :bs, reject_if: :all_blank, allow_destroy: true
validates_associated :bs
after_update :cascade_update!
def cascade_update!
# http://api.rubyonrails.org/classes/ActiveRecord/Batches.html#method-i-find_each
bs.find_each(batch_size: 100) do |b|
b.update!(updated_at: Time.zone.now)
end
end
end