Validation errors in has_one/belongs_to relationships

I have two objects, QuoteInput and Insured.

QuoteInput has one Insured and Insured belongs to QuoteInput.

I don’t understand what I’m seeing.

I assign an Insured to a QuoteInput. The Insured object has invalid
data.

I call save! on the quote input. QuoteInput has no validations.

I expect two things to happen - 1) an exception should be thrown,
indicating that there was a problem saving the child object, and 2) an
error message should be added to the quote_input object’s error message
array to indicate an error saving the child (Insured) object.

I know that the validation works on the insured object alone if I create
one and attempt to save it with invalid data.

Why does qi.save! return true below? It’s like it didn’t try to save
the insured object.

In script/console I see:

ins = Insured.new
=> #<Insured:0x37345e0 @new_record=true, @attributes={“city”=>"",
“address1”=>""
, “name”=>"", “updated_at”=>nil, “address2”=>nil, “zip_code”=>"",
“dba_name”=>ni
l, “quote_input_id”=>nil, “created_at”=>nil, “state”=>""}>

ins.save!
ActiveRecord::RecordInvalid: Validation failed: Name can’t be blank, Zip
code co
de is invalid
from
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_recor
d/validations.rb:748:in `save!’
from (irb):97
from â?¥:0

qi = QuoteInput.new
=> #<QuoteInput:0x36fb040 @new_record=true, @program_answers=[],
@attributes={“p
rogram_id”=>0, “updated_at”=>nil, “program_quote_input_type”=>"",
“program_quote
_input_id”=>0, “user_id”=>0, “created_at”=>nil}, @company_answers=[]>

qi.insured = ins
=> #<Insured:0x37345e0 @new_record=true,
@errors=#<ActiveRecord::Errors:0x372594
0 @errors={“name”=>[“can’t be blank”], “zip_code”=>[“code is invalid”]},
@base=#
<Insured:0x37345e0 …>>, @attributes={“city”=>"", “address1”=>"",
“name”=>"", "
updated_at"=>nil, “address2”=>nil, “zip_code”=>"", “dba_name”=>nil,
“quote_input
_id”=>nil, “created_at”=>nil, “state”=>""}>

qi.save!
=> true

Wes

More succinctly stated, does the saving of an object (A) that :has_one
child object (B) cause an error to be attached to the object (A) if the
child object (B) save fails?

Wes

Hello,
I’m wondering if you evere managed to resolve this issue? I’m having
the same problem…
Thanks,
Eddie

I thought that perhaps using the build_<child_object> method that you
get from declaring :has_one <other_object> might help. The console
output is below.

What I get from this is that, given A and B where A :has_one B:

  1. A.save! causes a save attempt on B
  2. If B’s save fails, then B gets errors put on its error array, A.save!
    returns true, and no exception is thrown.

This implies to me that if I want to be sure that A.save! successfully
saved B, then I have to override A.save! to inspect B’s error array and
then handle that.

Frankly, if I have to override save! in order to figure out whether the
child objects actually saved, then what’s the point of save! calling
save on the children for me? That’s only going to save me effort when
I’m absolutely sure (and when can you be absolutely sure) that the
child objects will be saved successfully.

I will set up a simpler test case and reverify this result soon.

Thanks,
Wes

==========================================

qi = QuoteInput.new
=> #<QuoteInput:0x39c3fc0 @new_record=true, @program_answers=[],
@attributes={“p
rogram_id”=>0, “updated_at”=>nil, “program_quote_input_type”=>"",
“program_quote
_input_id”=>0, “user_id”=>0, “created_at”=>nil}, @company_answers=[]>

qi.build_insured
=> #<Insured:0x394e048 @new_record=true, @attributes={“city”=>"",
“address1”=>""
, “name”=>"", “updated_at”=>nil, “address2”=>nil, “zip_code”=>"",
“dba_name”=>ni
l, “quote_input_id”=>nil, “created_at”=>nil, “state”=>""}>

qi
=> #<QuoteInput:0x39c3fc0 @new_record=true, @program_answers=[],
@attributes={“p
rogram_id”=>0, “updated_at”=>nil, “program_quote_input_type”=>"",
“program_quote
_input_id”=>0, “user_id”=>0, “created_at”=>nil},
@insured=#<Insured:0x394e048 @n
ew_record=true, @attributes={“city”=>"", “address1”=>"", “name”=>"",
“updated_at
“=>nil, “address2”=>nil, “zip_code”=>””, “dba_name”=>nil,
“quote_input_id”=>nil,
“created_at”=>nil, “state”=>""}>, @company_answers=[]>

qi.save!
=> true

qi.errors
=> #<ActiveRecord::Errors:0x3944430 @errors={},
@base=#<QuoteInput:0x39c3fc0 @ne
w_record=false, @program_answers=[],
@errors=#<ActiveRecord::Errors:0x3944430 …
.>, @new_record_before_save=true, @attributes={“program_id”=>0,
“updated_at”=>Fr
i Oct 13 16:12:40 Central Daylight Time 2006,
“program_quote_input_type”=>"", “p
rogram_quote_input_id”=>0, “id”=>280, “user_id”=>0, “created_at”=>Fri
Oct 13 16:
12:40 Central Daylight Time 2006}, @insured=#<Insured:0x394e048
@new_record=true
, @errors=#<ActiveRecord::Errors:0x3932a00 @errors={“name”=>[“can’t be
blank”]},
@base=#<Insured:0x394e048 …>>, @attributes={“city”=>"",
“address1”=>"", “name
“=>””, “updated_at”=>nil, “address2”=>nil, “zip_code”=>"",
“dba_name”=>nil, “quo
te_input_id”=>280, “created_at”=>nil, “state”=>""}>,
@company_answers=[]>>

qi.insured.errors
=> #<ActiveRecord::Errors:0x3932a00 @errors={“name”=>[“can’t be
blank”]}, @base=
#<Insured:0x394e048 @new_record=true,
@errors=#<ActiveRecord::Errors:0x3932a00 .
…>, @attributes={“city”=>"", “address1”=>"", “name”=>"",
“updated_at”=>nil, “ad
dress2”=>nil, “zip_code”=>"", “dba_name”=>nil, “quote_input_id”=>280,
“created_a
t”=>nil, “state”=>""}>>

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs