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