0

두 모델이 있습니다 (AB을 호출 할 수 있습니다).레일스는 중첩 된 특성을 가진 콜백 before_update를 호출합니다.

Ahas_manyb들과 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 

BAsome_enum_value 세트가 some_field 경우에 설정하는 before_update 콜백을 갖는다. 나는 속성 양식 B를 업데이트 할 경우 B에서 before_update 만 호출되고 있음이 관계가 중첩 된 형태에 사용되기 때문에

. 값 양식 A 만 변경하면 콜백이 호출되지 않습니다.

A을 업데이트하면 어떻게 Bbefore_update으로 전화 할 수 있습니까?

미리 감사드립니다. 잠재적 재앙 성능 결과를 초래할 수 있기 때문에 (그러나이 옵션을 has_many 관계가 존재하지 않습니다

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

당신이 B. 를 업데이트 할 때 a.updated_at을 업데이트 : 협회에 속한 들어

답변

2

당신은 touch 옵션을 사용할 수 있습니다 A에 1000s 이상이있는 경우).

당신은 그러나 자신의 롤 수 있습니다

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