# Has\_one/belongs\_to -- accessing the subordinate

**URL:** <https://www.ruby-forum.com/t/has-one-belongs-to-accessing-the-subordinate/188421>\
**Category:** Rails\
**Created:** [May 11, 2010, 6:41pm UTC](https://www.ruby-forum.com/t/has-one-belongs-to-accessing-the-subordinate/188421 "2010-05-11T18:41:51Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![fearless\_fool](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5e9695/32.png) [@fearless\_fool](https://www.ruby-forum.com/u/fearless_fool)\
**Post date:** [May 11, 2010, 6:41pm UTC](https://www.ruby-forum.com/t/has-one-belongs-to-accessing-the-subordinate/188421/1 "2010-05-11T18:41:51Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![fearless\_fool](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5e9695/32.png) [@fearless\_fool](https://www.ruby-forum.com/u/fearless_fool)\
**Post date:** [May 12, 2010, 12:53pm UTC](https://www.ruby-forum.com/t/has-one-belongs-to-accessing-the-subordinate/188421/2 "2010-05-12T12:53:17Z")

</div>

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.
