3

我有一个名为 Purchase 的模型,其中包含一个名为 tickets 和 amount 的字段。这个模型属于Event,它是有价格的。我想在创建新的 Purchase 后调用 update_amount 回调,但在回调方法中,关联的事件似乎不存在。

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:我最终在回调中添加了一个守卫,因此如果 Event 为 nil,它就不会被调用。不过,这只是一个 hack,有朝一日能彻底解决这个问题会很棒。

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 回答