# Has\_one prematurely nullifies existing association when assi

**URL:** <https://www.ruby-forum.com/t/has-one-prematurely-nullifies-existing-association-when-assi/89230>\
**Category:** Rails\
**Created:** [March 18, 2007, 11:15pm UTC](https://www.ruby-forum.com/t/has-one-prematurely-nullifies-existing-association-when-assi/89230 "2007-03-18T23:15:25Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![brian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/97f17d/32.png) [@brian](https://www.ruby-forum.com/u/brian)\
**Post date:** [March 18, 2007, 11:15pm UTC](https://www.ruby-forum.com/t/has-one-prematurely-nullifies-existing-association-when-assi/89230/1 "2007-03-18T23:15:25Z")

</div>

Like a number of other Rails newbies, I’m seeing some unexpected  
behavior with the has\_one relationship. I attempted to search for a  
solution or explanation here and on Rails Trac, but came up short.  
I’m using Rails 1.2.2. Here are some simplified models:

class Order \< ActiveRecord::Base  
has\_one :invoice  
validates\_associated :invoice  
end

class Invoice \< ActiveRecord::Base  
belongs\_to :order  
validates\_presence\_of :description  
end

The following works as expected (with output edited for brevity):

> > order = Order.create  
> > =\> #\<Order:0x3506fb0 … @attributes={“id”=\>1}\>
> 
> > invoice = Invoice.create(:description =\> “Foo”)  
> > =\> #\<Invoice:0x34f24e8 … @attributes={“order\_id”=\>nil, “id”=\>1,  
> > “description”=\>“Foo”}\>
> 
> > order.invoice = invoice  
> > =\> #\<Invoice:0x34f24e8 … @attributes={“order\_id”=\>1, “id”=\>1,  
> > “description”=\>“Foo”}\>
> 
> > Order.find(1).invoice  
> > =\> #\<Invoice:0x34e7688 @attributes={“order\_id”=\>“1”, “id”=\>“1”,  
> > “description”=\>“Foo”}\>

However, when I assign an invalid Invoice to the has\_one association,  
the valid association is nullified in the database:

> > order.invoice = Invoice.new  
> > =\> #\<Invoice:0x34e5810 … @errors={“description”=\>[“can’t be  
> > blank”]} … \>
> 
> > Order.find(1).invoice  
> > =\> nil

This behavior is surprising. Here’s another example (starting by  
reassigning the valid Invoice)

> > order.invoice = invoice  
> > order.build\_invoice  
> > =\> #\<Invoice:0x34bbd08 @new\_record=true, @attributes={“order\_id”=\>1,  
> > “description”=\>nil}\>
> 
> > Order.find(1).invoice  
> > =\> nil

I realize that understanding how and when things are saved can be  
confusing, especially with the has\_one relationship. I’m also aware  
of several ways to work around this, either by adding special code to  
Order, or just assigning to the belongs\_to association instead. But  
can someone explain why ActiveRecord seems to be nullifying a valid  
association before the new association is validated or saved?

Thanks,  
Brian

---

<div class="post-metadata">

**Author:** ![brian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/97f17d/32.png) [@brian](https://www.ruby-forum.com/u/brian)\
**Post date:** [March 19, 2007, 8:43pm UTC](https://www.ruby-forum.com/t/has-one-prematurely-nullifies-existing-association-when-assi/89230/2 "2007-03-19T20:43:34Z")

</div>

Anyone? Watching the development log show that ActiveRecord is  
setting the order\_id to null when the assignment is made.

---

<div class="post-metadata">

**Author:** ![brian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/97f17d/32.png) [@brian](https://www.ruby-forum.com/u/brian)\
**Post date:** [March 19, 2007, 10:20pm UTC](https://www.ruby-forum.com/t/has-one-prematurely-nullifies-existing-association-when-assi/89230/3 "2007-03-19T22:20:27Z")

</div>

Save the invoice after associating it with the order.

-Jonathan.

---

<div class="post-metadata">

**Author:** ![brian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/97f17d/32.png) [@brian](https://www.ruby-forum.com/u/brian)\
**Post date:** [March 20, 2007, 9:08pm UTC](https://www.ruby-forum.com/t/has-one-prematurely-nullifies-existing-association-when-assi/89230/4 "2007-03-20T21:08:38Z")

</div>

Hi, if the invoice is invalid, it isn’t saved to the database.  
Therefore, you’re overwriting the previous value of the invoice  
associated to the order. Thus, invoking find returns nil. Well, I  
wish that this helps.

Good luck,

-Conrad

---

<div class="post-metadata">

**Author:** ![brian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/97f17d/32.png) [@brian](https://www.ruby-forum.com/u/brian)\
**Post date:** [March 21, 2007, 7:02am UTC](https://www.ruby-forum.com/t/has-one-prematurely-nullifies-existing-association-when-assi/89230/5 "2007-03-21T07:02:30Z")

</div>

Hi, here’s a better explaination with the relevant code that you have  
posted:

1. 

> > order.invoice = Invoice.new  
> > =\> #\<Invoice:0x34e5810 … @errors={“description”=\>[“can’t be  
> > blank”]} … \>

2. 

> > Order.find(1).invoice  
> > =\> nil

Line 1 =\> We’re assigning the result or ‘Invoice.new’ where all field  
are initialized to  
their respective default values. Also, the  
validations are not invoked until  
you attempt to invoke save or save! methods. Thus,  
you’re assigning an  
invalid invoice instance to the order.invoice

Line 2 =\> Now, we’re trying to find an invoice instance that results  
in nil being returned  
because the invoice instance in (1) was never saved  
the database.

Finally, I would recommend taking a look at the relevant chapters in  
AWDwRv2 for additional information.

Good luck,

-Conrad

---

<div class="post-metadata">

**Author:** ![brian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/97f17d/32.png) [@brian](https://www.ruby-forum.com/u/brian)\
**Post date:** [March 20, 2007, 8:36pm UTC](https://www.ruby-forum.com/t/has-one-prematurely-nullifies-existing-association-when-assi/89230/6 "2007-03-20T20:36:33Z")

</div>

I’m not sure what you’re trying to say…yes, if I just assigned the  
the order to the invoice, then saved the invoice, that would  
workaround this issue. But that doesn’t answer my question. While  
playing around with this, it also looks like AR is nullifying the  
association in the Invoice object, as well. So, for example:

> > order = Order.create  
> > =\> #\<Order:0x3506fb0 … @attributes={“id”=\>1}\>
> 
> > invoice = invoice.create(:description =\> “Foo”)  
> > =\> #\<Invoice:0x34f24e8 … @attributes={“order\_id”=\>nil, “id”=\>1,  
> > “description”=\>“Foo”}\>
> 
> > order.invoice = invoice  
> > =\> #\<Invoice:0x34f24e8 … @attributes={“order\_id”=\>1, “id”=\>1,  
> > “description”=\>“Foo”}\>

> > Order.find\_first.invoice  
> > =\> #\<Invoice:0x34e79f8 @attributes={“order\_id”=\>“1”, “id”=\>“1”,  
> > “description”=\>“Foo”}\>
> 
> > Invoice.find\_first.order  
> > =\> #\<Order:0x34e2cc8 @attributes={“id”=\>“1”}\>

> > order.build\_invoice  
> > =\> #\<Invoice:0x34e1a58 @new\_record=true, @attributes={“order\_id”=\>1,  
> > “description”=\>nil}\>
> 
> > invoice.order  
> > =\> nil
> 
> > Invoice.find\_first.order  
> > =\> nil

Why is the Invoice with id = 1 no longer referencing order with id =  
1? All I’ve done is build a new invoice…I haven’t tried to save it,  
and it’s not even valid. And I can’t just re-save the original  
Invoice object, because it also no longer references the order. This  
seems like a bad side-effect to me.

As I’ve said, I’m a Rails newbie, and it seems like the general wisdom  
is to assign to the belongs\_to side of an association, instead of the  
has\_one side. But it would be nice if the has\_one side didn’t have  
surprising side-effects. Is this a well-known bug that I just didn’t  
search for long enough before I posted to this group?

Brian
