0

У меня есть две модели (давайте позвоним тогда A и B).Rails before_update обратный вызов с вложенными атрибутами

Ahas_manyb s и Bbelongs_toA.

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 всухую еслиA имеет some_enum_value набор.

Поскольку это соотношение используется на вложенной форме, что before_update из B только вызывается, если я обновлю форму атрибута B. Если я изменю только значение A, этот обратный вызов не вызывается.

Как я могу позвонить Bbefore_update, когда обновлен A?

Заранее спасибо.

ответ

2

Для принадлежит ассоциациям вы можете использовать touch вариант:

class B < ApplicationRecord 
    belongs_to :a, inverse_of: :bs, touch: true 
end 

Что бы обновить a.updated_at при обновлении B. Однако этот вариант не существует для 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.touch 
    end 
    end 
end 
+2

С точки зрения масштабирования вы должны быть очень осторожны, когда делаете что-то вроде этого. Операции записи являются дорогостоящими и обычно вы можете решить эту проблему путем проксирования или использования соединений. – max

+0

Большое спасибо, Макс. – ThalesMiguel

 Смежные вопросы

  • Нет связанных вопросов^_^