2012-06-02 81 views
8

我有兩個模型與一對多關聯。我想根據父項的某些狀態在初始化時在子模型上設置默認值。這涉及到需要通過belongs_to關聯訪問父對象的child的after_initialize回調觸發器。問題是,當我使用構建方法實例化子對象時,與父對象的關聯在after_initialize回調中爲零。這是預期的行爲?我在軌道3.0.6Rails協會在after_initialize無

,一種玩具,例如:

class Merchant < ActiveRecord::Base 
    has_many :products 
end 

class Product < ActiveRecord::Base 
    belongs_to :merchant 

    after_initialize :set_default_value 

    def set_default_value 
     if merchant.state 
      self.foo = some_value 
     else 
      self.foo = some_other_value 
     end 
    end 
end 

而在一個控制器:

product = merchant.products.build 

在調用set_default_value,商戶零,雖然它似乎不該不會的。

+1

具有原始商戶實例被保存呢,你叫商人了。 products.build? – Pasted

+0

是的,商家將是一個現有的記錄在分貝,所以它會有一個有效的ID。 – Dino

+1

我幾乎完全按照你的想法試過它,它對我很有用。唯一的區別是'class Products'應該是'class Product'而不是's'。 –

回答

1

如下我會改變代碼:

class Product < ActiveRecord::Base 
    ... 
    def set_default_value(state = merchant.state) 
    if state 
     self.foo = some_value 
    else 
     self.foo = some_other_value 
    end 
    end 
end 

然後改變你的來電者:

product = merchant.products.build(:state => merchant.state) 

而且,我發現after_initialize回調是緩慢的。因此,另一種選擇是將邏輯轉移到產品的構建器中。

product = merchant.products.build(:foo => merchant.state ? some_value : some_other_value) 

這也消除得墨忒耳定律違反從代碼(即產品不應該知道/關心商戶的狀態是什麼)。

0

我在軌道上2.3,我可以證實,

product = merchant.products.build 

在after_initialize回調將不會返回正確的MERCHANT_ID協會

,但我發現,它會與

正常工作
product = merchant.products.new 

我認爲它是用這個提交修復的(我真的不知道,但我並不真正熟悉git工作流程):

https://github.com/rails/rails/issues/1842

因爲在軌3.1.11它同時適用於buildnew

0

你可能找inverse_of

has_many :products, inverse_of: :merchant