簡體   English   中英

Ruby on Rails - 嵌套屬性:如何從子模型訪問父模型

[英]Ruby on Rails - nested attributes: How do I access the parent model from child model

我有幾個這樣的模特

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表單中的嵌套屬性中讀取bill_items時,屬性bill_item.bill_id或bill_item.bill在保存之前不可用。

那我該怎么做呢?

這就是我最終解決的問題; 通過在回調上設置父級

  has_many :bill_items, :before_add => :set_nest

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

在Rails 4中(未在早期版本上測試),您可以通過在has_manyhas_one上設置inverse_of選項來訪問父模型:

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

  accepts_nested_attributes_for :bill_items
end

文檔: 雙向關聯

bill_item.bill應該可用,您可以嘗試提升self.bill.inspect以查看它是否存在,但我認為問題出在其他地方。

我通過在回調中設置父“來修復”它:

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方法完成了這個伎倆。 希望它與accepts_nested_attributes_for一起標准化。

是的,這種問題可能很煩人。 您可以嘗試將虛擬屬性添加到Bill Item模型,如下所示:

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是可取的,但它可能不是一個問題。 如果這有幫助,請告訴我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM