Forum: Ruby on Rails Assigning has_many child in parent creation question

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Chris R. (Guest)
on 2006-02-14 12:34
(Received via mailing list)
If I have...

class Parent
   has_many :children
end

class Child
   belongs_to :parent
end

...then...

* Assigning a _new_ child during parent's creation saves the child
record with the parent's id.
   child = Child.new
   Parent.create(:children => [child])
   # Results in child being associated with parent

* Assigning an existing child after a parent's creation saves the child
record with the parent's id.
   child = Child.new
   parent = Parent.new
   parent.children << child
   # Results in child being associated with parent

...however...

* Assigning an _existing_ child during parent's creation does not save
the child's record with the parent's id.
   child = Child.create
   Parent.create(:children => [Child.new])
   # Child is not associated with parent

This seems slightly counter-intuitive; unless I am missing something
obvious.  Any thoughts?

Chris
Chris R. (Guest)
on 2006-02-14 13:13
Sorry, the last example is incorrect - I should be using the new child
in my parent construction

  child = Child.create
  Parent.create(:children => child)

Chris


Chris R. wrote:
> If I have...
>
> class Parent
>    has_many :children
> end
>
> class Child
>    belongs_to :parent
> end
>
> ...then...
>
> * Assigning a _new_ child during parent's creation saves the child
> record with the parent's id.
>    child = Child.new
>    Parent.create(:children => [child])
>    # Results in child being associated with parent
>
> * Assigning an existing child after a parent's creation saves the child
> record with the parent's id.
>    child = Child.new
>    parent = Parent.new
>    parent.children << child
>    # Results in child being associated with parent
>
> ...however...
>
> * Assigning an _existing_ child during parent's creation does not save
> the child's record with the parent's id.
>    child = Child.create
>    Parent.create(:children => [Child.new])
>    # Child is not associated with parent
>
> This seems slightly counter-intuitive; unless I am missing something
> obvious.  Any thoughts?
>
> Chris
Chris R. (Guest)
on 2006-02-14 13:17
Err, apparently I'm more stoopid than I realised.  This should of course
be

  child = Child.create
  Parent.create(:children => [child])

Regardless of my ineptitude, this is the example that does not assign
the child to the parent (i.e. child.parent_id is null in database).

Chris

Chris R. wrote:
> Sorry, the last example is incorrect - I should be using the new child
> in my parent construction
>
>   child = Child.create
>   Parent.create(:children => child)
>
> Chris
>
Byron S. (Guest)
on 2006-02-14 16:13
(Received via mailing list)
In your final example the "child = Child.create" line is irrelevant,
right?
"child" is never used. What happens when you do use it? That should
definitely work.

- Byron
Nick S. (Guest)
on 2006-02-14 16:13
(Received via mailing list)
Try this...

Parent.children << Child.new

See what happens...
Chris R. (Guest)
on 2006-02-14 16:21
I probably should have been slightly more explicit in my initial
example.

What you suggest works fine.  The reason that your method works is the
basis for my confusion.

With an unsaved child object, both methods (as well as
update_attribute/s) work fine.

With a previously saved child object, only the assignment on parent
creation doesn't work - all other methods do.  This is what seems
counter-intuitive to me.

Chris
Nick S. (Guest)
on 2006-02-14 18:16
(Received via mailing list)
The initial problem with the your code (I believe)  is that while you
were assigning the parent/child relationship you weren't saving the
child again once you did so. As far as I know, the only method that
will actually save/create the child, or related objects, is the <<
operator.

In other words, if you set the parent_id explicitly then you need to
call child.save. Try adding that in your original code after the call
to the parent object.

-Nick
Anthony G. (Guest)
on 2006-02-14 22:02
> With a previously saved child object, only the assignment on parent
> creation doesn't work - all other methods do.  This is what seems
> counter-intuitive to me.

The Agile book seems to indicate something like
child.create_parent(attributes={})

Tony
Chris R. (Guest)
on 2006-02-15 10:16
Nick S. wrote:
> The initial problem with the your code (I believe)  is that while you
> were assigning the parent/child relationship you weren't saving the
> child again once you did so. As far as I know, the only method that
> will actually save/create the child, or related objects, is the <<
> operator.
>
> In other words, if you set the parent_id explicitly then you need to
> call child.save. Try adding that in your original code after the call
> to the parent object.
>
> -Nick

Thanks for all the pointers folks.

Just for clarity; I already knew how to achieve what I required.  I
guess my question was more about the principle of least surprise.  For
each method available to 'join' a parent and child; all work whether or
not the child is saved; _except_ the parent creation method.  This just
surprised me is all.

Thanks for the input,

Chris
This topic is locked and can not be replied to.