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
<li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org>
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
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
> To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe@googlegroups.com.
> 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
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.