在after_initialize回调中,Rails关联为nil

时间:2012-08-16 18:03:08

标签: ruby-on-rails activerecord callback

我有一个名为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则不会调用它。不过,这只是一个黑客攻击,而且有时候能够深入解决这个问题。

1 个答案:

答案 0 :(得分:0)

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

after_initialize就像Ruby对象的构造函数 - 在将任何数据库信息加载到该对象之前调用它。

您可能想要的是:before_save回调以根据门票和价格设置金额。本质上,“在我自救之前,根据我当前的门票数量和门票的价格重新计算我的金额。然后,把我写到数据库。”