Spec-ing a nested object is saved on the specs of the object it is nested into

hi there,
I have a Rails model A, that has_one model B, model A have a method
called
save_nested_b that:

  • context ‘invalid B params’
    ** context ‘no nested B exists’ => do nothing
    ** context ‘nested B exists’ => remove it

  • context ‘valid B params’
    ** context ‘no nested B exists’ => create it
    ** context ‘nested B exists’ => remove it and create new one (or edit
    attributes linking to A)

the save_nested_b method implementation should not be problematic. My
question is:

on A specs I want to make sure all above on the list happens but not
having
to repeat all B validations on making ‘invalid B params’ examples,
because B
have its own specs, and also the A specs for save_nested_b will be
brittle
when B validations change (not to mention the combinations of invalid
fields
can be long)

how would you do this? would you do a loose thing like:

context ‘invalid B params’ do

a.save_nested_b nil
a.should have_no_b

end

giving it a more thought after writing this email I guess I would go for
this approach, what do you think?

greetings,
joaquin

On Fri, Mar 12, 2010 at 7:45 AM, Joaquin Rivera P.
[email protected] wrote:

attributes linking to A)
how would you do this? would you do a loose thing like:

context ‘invalid B params’ do

a.save_nested_b nil
a.should have_no_b

end

giving it a more thought after writing this email I guess I would go for this approach, what do you think?

Depends on who is calling save_nested_b. I usually save associations
via callbacks as part of the save operation, and wouldn’t call
save_nested_b from outside the A object. In that case, I’d treat
save_nested_b as a private method and likely not spec it directly.
i.e.

a = A.create!(valid_a_attributes, :b => valid_b_attributes)
a.should have_a_b

a = A.create!(valid_a_attributes, :b => invalid_b_attributes)
a.should have_no_b

etc

WDYT?

David

thanks for your reply David,
what worried me (well, got me thinking) was having to put on A’s specs
too
much knowledge about when B’s attributes were valid or not. I ended up
doing
more or less what you expose, but only:

  • using nil as the invalid input
  • using one valid combination for the valid ones

greetings,
joaquin

2010/3/15 David C. [email protected]