20

私はそのようなモデルをいくつか持っています

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 が保存される前に使用できないため、上記の検証は明らかに機能しません。

では、どうすればそのようなことをすることができますか?

4

5 に答える 5

18

これが最終的に解決した方法です。コールバックで親を設定することにより

  has_many :bill_items, :before_add => :set_nest

private
  def set_nest(bill_item)
    bill_item.bill ||= self
  end
于 2011-02-19T06:39:28.270 に答える
9

Rails 4 (以前のバージョンではテストしていません) では、inverse_ofオプションを onhas_manyまたはに設定することで、親モデルにアクセスできhas_oneます。

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

  accepts_nested_attributes_for :bill_items
end

ドキュメンテーション:双方向の関連付け

于 2015-04-22T21:47:36.067 に答える
1

bill_item.bill は利用可能である必要があります。レイズ self.bill.inspect を実行して、そこにあるかどうかを確認できますが、問題は別の場所にあると思います。

于 2010-04-25T15:15:08.627 に答える
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 メソッドがうまくいきました。それがaccepts_nested_attributes_forで標準になったことを願っています。

于 2011-01-28T08:54:35.370 に答える
0

ええ、この種の問題は面倒です。次のように、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 を含めるのは望ましくないかもしれませんが、問題にはならないかもしれません。これが役立つかどうか教えてください。

于 2010-04-10T17:12:12.453 に答える