3

チケットと金額という名前のフィールドを持つ Purchase という名前のモデルがあります。このモデルは、価格のある Event に属します。新しい Purchase が作成された後に update_mount コールバックを呼び出したいのですが、コールバック メソッドに関連付けられたイベントが存在しないようです。

class Purchase < ActiveRecord::Base
  belongs_to :event
  attr_accessible :event_id, :tickets, :amount
  delegate :price, to: :event
  after_initialize :update_amount
  ...
  def update_amount
   update_attribute :amount, self.tickets * self.price
  end
end

class Event < ActiveRecord::Base
  attr_accessible :price
  ...
end

しかし、私がそれをテストしたとき、私は次のことに出くわしました:

$ Purchase.new(tickets: 2, event_id: 1541)  
RuntimeError: Purchase#price delegated to event.price, but event is nil: <Purchase
id: nil, user_id: nil, event_id: nil, amount: nil, tickets: 1,
event_date: nil, created_at: nil, updated_at: nil, checkout_id: nil,
checkout_uri: nil, state: "incomplete">

システムには ID 1541 のイベントがありますが、ActiveRecord はそれにアクセスできないことに注意してください。event.price を使用して、デリゲートなしで同じことを試してみましたが、同じことが起こりました。つまり、価格が NilClass エラーで見つかりませんでした。

誰かがこれを理解するのを手伝ってくれますか? after_initializeブロック内で関連が形成されていませんか?私が見落としているものはありますか?


PS: コールバックにガードを追加して、イベントが nil の場合に呼び出されないようにしました。ただし、これは単なるハックであり、いつかこの問題の真相を解明できれば幸いです。

4

1 に答える 1

0

http://edgeguides.rubyonrails.org/active_record_callbacks.html#after-initialize-and-after-find

after_initialize は、Ruby オブジェクトのコンストラクタのようなものです。データベース情報がそのオブジェクトにロードされる前に呼び出されます。

おそらく必要なのは、チケットと価格に基づいて金額を設定する :before_save コールバックです。要するに、「自分を救う前に、現在のチケット数とそれらのチケットの価格に基づいて金額を再計算します。次に、データベースに書き込みます。」

于 2013-06-04T13:13:35.510 に答える