2010-04-09 139 views
20

訪問父模型我有像這樣Ruby on Rails的 - 嵌套的屬性:我如何從子模型

class Bill < ActiveRecord::Base 
    has_many :bill_items 
    belongs_to :store 

    accepts_nested_attributes_for :bill_items 
end 

class BillItem <ActiveRecord::Base 
    belongs_to :product 
    belongs_to :bill 

    validate :has_enough_stock 

    def has_enough_stock 
    stock_available = Inventory.product_is(self.product).store_is(self.bill.store).one.quantity 
    errors.add(:quantity, "only #{stock_available} is available") if stock_available < self.quantity 
    end 
end 

以上驗證了幾個模型,是因爲當我讀顯然是行不通的從票據表格內嵌套的屬性bill_items,屬性bill_item.bill_id或bill_item.bill未保存之前可用。

那我怎麼去這樣做類似的東西?

+0

我解決了這個加入電話回聯想,:before_add =>:set_nest – TMaYaD 2011-02-19 06:35:40

回答

18

這是我如何解決它最終;通過回調

has_many :bill_items, :before_add => :set_nest 

private 
    def set_nest(bill_item) 
    bill_item.bill ||= self 
    end 
+1

是啊!它最近一直在竊聽我。我希望它是自動的,如果回叫函數是針對關聯代理(如關聯擴展)而不是關聯所有者運行的,則可以編寫更通用的版本。 – ilpoldo 2011-03-24 18:22:34

0

是啊,這種問題可以是惱人。你可以嘗試添加一個虛擬屬性到您的帳單項目模型是這樣的:

class BillItem <ActiveRecord::Base 
    belongs_to :product 
    belongs_to :bill 

    attr_accessible :store_id 

    validate :has_enough_stock 

    def has_enough_stock 
    stock_available = Inventory.product_is(self.product).store_is(load_bill_store).one.quantity 
    errors.add(:quantity, "only #{stock_available} is available") if stock_available < self.quantity 
    end 

    private 

    def load_bill_store 
    Store.find_by_id(self.store_id) 
    end 
end 

,然後在視圖中,您可以添加一個隱藏字段這樣的:

<%= bill_item.hidden_field :store_id, :value => store_id %> 

這還沒有測試,但它可能工作。您可能無法在html中使用store_id,但它可能不是問題。讓我知道這是否有幫助。

1

的bill_item.bill應該可以,你可以嘗試做加薪self.bill.inspect,看看它的存在與否,但我認爲這個問題是在其他地方。

+0

就算是不可用,則可能OP只需添加一個before_validation回調來設置。 BillItems不需要知道他們自己的ID或父母Bill的ID來驗證。 – hornairs 2010-05-12 13:51:05

1

我在回調設置父「固定」它:

class Bill < ActiveRecord::Base 
    has_many :bill_items, :dependent => :destroy, :before_add => :set_nest 
    belongs_to :store 

    accepts_nested_attributes_for :bill_items 

    def set_nest(item) 
    item.bill ||= self 
    end 
end 

class BillItem <ActiveRecord::Base 
    belongs_to :product 
    belongs_to :bill 

    validate :has_enough_stock 

    def has_enough_stock 
     stock_available = Inventory.product_is(self.product).store_is(self.bill.store).one.quantity 
    errors.add(:quantity, "only #{stock_available} is available") if stock_available < self.quantity 
    end 
end 

的set_nest方法奏效了。希望它的標準與accep_nested_attributes_for。

7

設置父在Rails 4(沒有測試早期版本),你可以通過設置在has_manyhas_oneinverse_of選項訪問父模型:

class Bill < ActiveRecord::Base 
    has_many :bill_items, inverse_of: :bill 
    belongs_to :store 

    accepts_nested_attributes_for :bill_items 
end 

文檔:Bi-directional associations

+0

對於導軌4,這是真實的答案 – Abs 2016-02-07 03:47:46

相關問題