似乎当子对象在setter中引用其父对象时,它无法初始化,除非在参数hash中首先给出外键。
class Bot < ActiveRecord::Base
has_many :items
end
class Item < ActiveRecord::Base
belongs_to :bot
def name=(text)
write_attribute(:name, "#{self.bot.name}'s #{text}")
end
end
Item.new(:name => 'pitchfork', :bot_id => 1, ... )
# => undefined method `name' for nil:NilClass (NoMethodError)
Item.new(:bot_id => 1, :name => 'pitchfork', ... )
# => #<Item id: nil, bot_id: 1, name: "r2d2's pitchfork", ... >请注意,在Ruby1.9中保留了散列键的顺序,但重点是,必须在引用其父对象的访问器之前设置bot_id。
因此,下面的代码也可以工作:
item = Item.new
item.bot_id = 1
item.attributes = { :name => 'pitchfork', ... }真正恼人的是,has_many集合上的build方法也不起作用,我认为如果有必要的话,这是打补丁的正确位置。
Bot.find(1).items.build(:name => 'pitchfork')
# => undefined method `name' for nil:NilClass (NoMethodError)解决这个问题的最好办法是什么,或者修补这个问题,或者我做错了什么?
发布于 2010-08-08 01:10:32
您可以将合并后的字符串移动到after_update回调。这样,在正确设置Bot模型之前,您就不必访问它了。
但是,我可能会将name保留为一个简单的字符串,然后为合并后的字符串添加一个虚拟属性。这样,如果Bot的名称发生更改,它也会更新。
class Item < ActiveRecord::Base
belongs_to :bot
def full_name
@full_name ||= "#{bot.name}'s #{name}"
end
endhttps://stackoverflow.com/questions/3431045
复制相似问题