With a has_one/belongs_to relationship, what's the best way to guarantee
that the belongs_to object gets created and is accessible alongside the
has_one object?  I *think* the after_create callback is a good choice,
but I discovered an oddity while trying it.

F'rinstance, if every horse has a carriage:
============
ActiveRecord::Schema.define do
  create_table(:horses) {|t| t.timestamps }
  create_table(:carriages) {|t| t.timestamps; t.integer :horse_id }
end
class Horse < ActiveRecord::Base
  after_create :create_carriage
  has_one :carriage, :dependent => :destroy
  private
    def create_carriage
      Carriage.create(:horse => self)
    end
end
class Carriage < ActiveRecord::Base
  belongs_to :horse
end
============
This works fine using create:
========
>> horse1 = Horse.create()
=> #<Horse id: 5, created_at: "2010-05-11 16:17:06", updated_at:
"2010-05-11 16:17:06">
>> horse1.carriage
=> #<Carriage id: 5, created_at: "2010-05-11 16:17:06", updated_at:
"2010-05-11 16:17:06", horse_id: 5>
========
It also works if you call Horse.new(), horse.save!() and *then*
horse.carriage():
========
>> seabiscuit = Horse.new()
=> #<Horse id: nil, created_at: nil, updated_at: nil>
>> seabiscuit.save!
=> true
>> seabiscuit.carriage
=> #<Carriage id: 6, created_at: "2010-05-11 16:19:29", updated_at:
"2010-05-11 16:19:29", horse_id: 6>
========
If you call horse.carriage *before* horse.save!(), it shows up as nil --
that's to be expected since there's nothing in the db to associate with.
But if you THEN call horse.save! followed by horse.carriage, it STILL
reports nil:
========
>> nellie = Horse.new
=> #<Horse id: nil, created_at: nil, updated_at: nil>
>> nellie.carriage
=> nil                 # no carriage because we haven't called save! yet
>> nellie.save!
=> true
>> nellie.carriage
=> nil                 # whoa, nellie!  where's your carriage???
========
... despite this, a carriage really was created for nellie:
========
>> nellie
=> #<Horse id: 9, created_at: "2010-05-11 16:27:11", updated_at:
"2010-05-11 16:27:11">
>> Carriage.find_by_horse_id(nellie.id)
=> #<Carriage id: 9, created_at: "2010-05-11 16:27:11", updated_at:
"2010-05-11 16:27:11", horse_id: 9>
========

I can imagine why this is happening: Calling horse.carriage caches a
value and doesn't bother to re-check the database after the save!.
Since I'm *sure* it's not a bug ;), I must be doing something improper.

How would a seasoned expert explain this?  (And is it documented
somewhere?)

Thanks.

- ff
-- 
Posted via http://www.ruby-forum.com/.

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en.

Reply via email to