ActiveRecord does query caching by default. If you use build instead of new when creating the child object the problem is solved, at least for has_many associations. I have no idea if this works with has_one associations.
Example of what I mean: >> @user = User.new(:name => 'bob') => #<User id: nil, name: "bob", age: nil, created_at: nil, updated_at: nil> >> @user.comments => [] >> @user.comments.build(:body => 'my comment') => #<Comment id: nil, user_id: nil, body: "my comment", created_at: nil, updated_at: nil> >> @user.save! => true >> @user.comments => [#<Comment id: 2, user_id: 3, body: "my comment", created_at: "2010-05-12 08:57:21", updated_at: "2010-05-12 08:57:21">] Replace build with new, and @user.comments will still return [] after @user has been saved. On May 11, 6:41 pm, Fearless Fool <[email protected]> wrote: > 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 viahttp://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 > athttp://groups.google.com/group/rubyonrails-talk?hl=en. -- 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.

