0

我有兩個模型(讓我們打電話然後AB)。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 

除此之外,Bbefore_update回調,設置some_field爲零如果Asome_enum_value集。

由於這關係被一個嵌套形式上使用,即從before_update如果B我更新屬性形式B纔會被調用。如果我只更改A的值表示回調未被調用。

A更新時,我怎麼能撥打Bbefore_update

在此先感謝。

回答

2

對於屬於關聯,你可以使用touch選項:

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

當你更新B. 這將更新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.touch 
    end 
    end 
end 
+2

但是,您可以滾你自己。寫操作很昂貴,通常你可以通過代理或使用連接來解決這個問題。 – max

+0

非常感謝,馬克斯。 – ThalesMiguel