It seems that when a child object has a reference to its parent in its setter, it fails to get initialized unless the foreign key is given first in the parameter 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", ... >
Note that the order of hash keys is preserved in Ruby 1.9, but the point is, bot_id
must be set before the accessor that has a reference to its parent.
So, the following code works too:
item = Item.new
item.bot_id = 1
item.attributes = { :name => 'pitchfork', ... }
What's really annoying is that the build
method on has_many collection doesn't work either, which I think is the right place to patch if I'd have to.
Bot.find(1).items.build(:name => 'pitchfork')
# => undefined method `name' for nil:NilClass (NoMethodError)
What's the best idea to get around this, or patch this, or am I doing anything wrong here?