0

理論:-でレコードを作成した後、customer bill2つの異なるモデルの2つのデータセットを送信しています。1セットのデータがに送信されledger、1セットのデータがに送信されledger_line_itemます。複雑なのは、データを送信した後、ledger_idに保存したいということledger_line_itemです。コードは次のとおりです

コード:-

class CustomerBill < ActiveRecord::Base
  after_create :creating_ledger_line_items, :creating_ledger_items

  def creating_ledger_items
    CustomerLedger.create(:customer_id =>self.customer_id,/*rest of attributes*/)
  end

  def creating_ledger_line_items
    CustomerLedgerLineItem.create(:customer_id =>self.customer_id,/*rest of attributes*/)
  end
end

元帳で私は書いた

class CustomerLedger < ActiveRecord::Base
  after_save :update_record_line_items

  def update_record_line_items
    a = CustomerLedgerLineItem.find_by_customer_id(self.customer_id)
    a.update_attributes(:customer_ledger_id => self.id)
  end
end

上記のコードはエラーなしで正常に動作しますが、ledger_idに投稿されていませんledger_line_items。このエラーが発生している理由を特定できませんか?請求書が作成された後に投稿ledger_idするという私の目標を達成することができる他の方法はありますか?ledger_line_itemsガイダンスが必要です。よろしくお願いします。

4

2 に答える 2

0

モデルは次のように変更できます。

私はあなたが持っていると仮定していますCustomer Model

class Customer < ActiveRecord::Base
  has_one :customer_ledger
  has_many :customer_ledger_line_items, :through => :customer_ledger   
  accepts_nested_attributes_for :customer_ledger

end

class CustomerLedger < ActiveRecord::Base
  has_many :customer_ledger_line_items
  accepts_nested_attributes_for :customer_ledger_line_items
end

class CustomerBill < ActiveRecord::Base
  belongs_to :customer
  after_create :creating_ledger_items, :creating_ledger_line_items

  def creating_ledger_line_items
   cl = self.customer.customer_ledger.build(your_attributes)
   cl.save!
  end

  def creating_ledger_items
    cli = self.customer.customer_ledger.customer_ledger_items.build(your_attributes)
    cli.save!     
  end
end
于 2013-03-02T07:22:26.240 に答える
0

*after_create* フックでモデルを作成したい場合のために、何が問題なのかを説明します。

Rails でモデルを作成し、*after_create*、*before_update* などのフックがある場合、すべての更新はトランザクションで発生するため、それらのいずれかが例外をスローした場合、何も更新されません。

この場合、トランザクション内で、まだ存在しない CustomerLedger の ID を取得しようとしています。これは、すべてがトランザクション内にあるため、トランザクションが実行されるまでレコードがデータベースに保存されないためです。 CustomerLedger#update_record_line_items では、self.id が常に nil であるためです。

codeit によって提案されたネストされた属性を使用することは、おそらく問題に対する最良の解決策ですが、ネストされた属性が高度なトピックであると思われる場合は、次のようなことができます。

class CustomerBill < ActiveRecord::Base

  after_create :created_leder_data

  def create_ledger_data
    customer_ledger = CustomerLedger.build(customer_id: self.customer_id, # Rest of attributes)
    customer_ledger.customer_ledger_line_items.build(customer_id: self.customer_id, # Rest of attributes)
    customer_ledger.save!
  end
end
于 2013-03-02T07:43:37.150 に答える