# Updating Child Records

**URL:** <https://www.ruby-forum.com/t/updating-child-records/125200>\
**Category:** Rails\
**Created:** [January 7, 2008, 12:15am UTC](https://www.ruby-forum.com/t/updating-child-records/125200 "2008-01-07T00:15:52Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [January 7, 2008, 12:15am UTC](https://www.ruby-forum.com/t/updating-child-records/125200/1 "2008-01-07T00:15:52Z")

</div>

I have a 3 level hierarchical data structure, for this example lets  
say it’s Bike (has many) Wheels (has many) Spokes.

Here’s what I want to do, update a bunch of Spokes that all belong to  
one Bike but do it all with one Save! method call.

I’ve tried loading the Bike, accessing, changing, and adding Spokes  
through the Bike.wheels.spokes collections then doing Bike.save! but  
it doesn’t work (the database remains unchanged). It DOES work  
however when I create a new bike record, add the wheels and spokes  
then save that.

So is there any way to have all the Spoke records saved with one call  
to save? I’m attempting to limit the number of individual SQL calls,  
cause there are a lot of spoke records and it will happen often.

Thanks in advance,  
Danny

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [January 7, 2008, 1:59am UTC](https://www.ruby-forum.com/t/updating-child-records/125200/2 "2008-01-07T01:59:19Z")

</div>

The problem with bike.wheels.spokes is because bike has many wheels, and  
_each wheel_ has many spokes. With bike.wheels.spokes, you’re trying to  
call  
spokes on the collection of all wheels for that bike, so it isn’t going  
to  
work! What you need to do is to find a single wheel, something a simple  
as @  
bike.wheels.first will do, or do @wheel = Wheel.find(id) and just find  
the  
one wheel.

To add spokes:

@bike.wheels.first.spokes.build(:spoke\_field\_1 =\> “blah”)

To remove a spoke:

@bike.wheels.first.spokes - Spoke.find(spoke\_id)

To edit a spoke:

@bike.wheels.first.spokes.find(id).update\_attributes(params[:spoke])

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [January 7, 2008, 2:46am UTC](https://www.ruby-forum.com/t/updating-child-records/125200/3 "2008-01-07T02:46:04Z")

</div>

I wouldn’t think that would work, because you’re not changing the  
associations themselves (i.e. adding/removing records), but you’re  
editing  
instances of the single records.

I can’t think of another way to do this, sorry. If it’s one value you  
could  
loop through and do update\_attribute(“field”,“value”), and  
update\_attributes  
which I guess you know about already.

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [January 7, 2008, 2:42am UTC](https://www.ruby-forum.com/t/updating-child-records/125200/4 "2008-01-07T02:42:34Z")

</div>

Sorry, I should have been more clear, I’m aware of how the collections  
work, that was pseudo-code. I’m doing it properly in my real code.

#Pseudo code  
b = bike.find(id)  
then I loop through b.wheels  
loop through wheel.spokes  
spoke.thing = “newvalue”  
end  
end

b.save!

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [January 7, 2008, 9:13am UTC](https://www.ruby-forum.com/t/updating-child-records/125200/5 "2008-01-07T09:13:11Z")

</div>

It was a hypothetical example, things in my real DB are all correct  
and don’t break any of the normal forms, one pk and one foreign key to  
link each record to it’s parent.

According to Ryan’s reply above, Save’s are only propagated (to  
descendents) in Ruby model objects when there are insertions or  
deletions, not when the fields have been changed.

Thanks,  
Danny

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [January 7, 2008, 3:58am UTC](https://www.ruby-forum.com/t/updating-child-records/125200/6 "2008-01-07T03:58:43Z")

</div>

On Jan 6, 3:14 pm, Daniel B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Here’s what I want to do, update a bunch of Spokes that all belong to  
> one Bike but do it all with one Save! method call.

I recommend (as I have in another thread) that you not do this.

Third normal form states that every column in a table should be  
dependent on the primary key. Well, in this case, one of the columns  
in the spokes table appears to be dependent not on its primary key,  
but on its associated bike’s primary key.

Just my $.02.

///ark

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [January 7, 2008, 11:46pm UTC](https://www.ruby-forum.com/t/updating-child-records/125200/7 "2008-01-07T23:46:11Z")

</div>

It’s true - they’re done automatically on create, but not on update.

Ryan B. covers this in his screencast on managing multiple models  
with 1 form ([#75 Complex Forms Part 3 - RailsCasts](http://railscasts.com/episodes/75)). It’s relatively  
simple to iterate through the child records using something like  
def save\_wheels  
wheels.each do |w|  
w.save(false)  
end  
end

It assumes of course that you have updated their attributes and have a  
has\_many :wheels in the Bike model.

and calling this method (of the Bike model) with a callback in the  
Bike model  
after\_update :save\_wheels

This way, the children are automatically saved when the parent is  
saved.

MC

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [January 7, 2008, 11:49pm UTC](https://www.ruby-forum.com/t/updating-child-records/125200/8 "2008-01-07T23:49:06Z")

</div>

eeew @ .save(false)

Take this as a warning to be very careful when using .save(false),  
passing  
in false skips all validations and you might not get desired results.

On Jan 8, 2008 9:15 AM, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> end
> 
> > deletions, not when the fields have been changed.
> > 
> > > > one Bike but do it all with one Save! method call.  
> > > > ///ark

–  
Ryan B.

> **[frozenplague.net](http://www.frozenplague.net)**
>
> This domain may be for sale!

Feel free to add me to MSN and/or GTalk as this email.
