Rails before_update 具有嵌套属性的回调
Rails before_update callback with nested attributes
我有两个模型(让我们调用 A
和 B
)。
A
has_many
b
和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
有一个 before_update
回调将 some_field
设置为零 if A
有 some_enum_value
设置.
由于此关系用于 嵌套形式 ,因此仅当我更新属性形式 [=14] 时才会调用 B
中的 before_update
=].如果我只更改值形式 A
,则不会调用该回调。
如何在 A
更新时调用 B
的 before_update
?
提前致谢。
对于属于协会,您可以使用 touch
选项:
class B < ApplicationRecord
belongs_to :a, inverse_of: :bs, touch: true
end
当您更新 B 时,它会更新 a.updated_at
。
然而,此选项对于 has_many
关系不存在,因为它可能具有潜在的灾难性性能后果(如果 A 有 1000 或更多 B)。
但是您可以自己滚动:
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
和 B
)。
A
has_many
b
和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
有一个 before_update
回调将 some_field
设置为零 if A
有 some_enum_value
设置.
由于此关系用于 嵌套形式 ,因此仅当我更新属性形式 [=14] 时才会调用 B
中的 before_update
=].如果我只更改值形式 A
,则不会调用该回调。
如何在 A
更新时调用 B
的 before_update
?
提前致谢。
对于属于协会,您可以使用 touch
选项:
class B < ApplicationRecord
belongs_to :a, inverse_of: :bs, touch: true
end
当您更新 B 时,它会更新 a.updated_at
。
然而,此选项对于 has_many
关系不存在,因为它可能具有潜在的灾难性性能后果(如果 A 有 1000 或更多 B)。
但是您可以自己滚动:
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