Updating children in a has_many relationship

If a parent has_many children, The children can be set using parent.children_ids = which is very cool. If the parent is a new record, nothing will happen until the parent is saved. If the parent is an existing record, the children will be immediately updated regardless of whether the parent has been modified or validated. In fact, the parent model will have no indication that the children have been modified at all.

Am I the only one that thinks this is odd behavior? It seems like there should be a more consistent approach.

Thanks, Tom

I don't think it's odd at all.... the only reason it's not saved until the Parent is initially saved is if the parent has no ID, how cna you assign parent_id to the child ( or the join table ).

If you're modifying the children w/o touching the parent.... say categories and posts in those categories.... It would be up to the category model to validate any changes you make to it... and if you changed a post in one of those categories... or changed the category the post belonged to... why shouldn't it be changed right away? Why would I need to re-validate the category?

Why shouldn't it be changed right away? Because the parent may be invalid.

Really, the problem is consistency. If are doing an update to the parent and children and the parent is invalid, the children may or may not be affected. The consistent way to handle it would be to not update the children until the parent is saved. IMHO

Thanks, Tom

I disagree... that should be up to the developer to check... like my example, why do I need to validate the category, each time I post?

My feeling is that if it's something that you need to have, then create a before_filter and have it validate, otherwise you're validating things that never change...

although I can see your argument for consistency... I still have no problem with the way it is now...

That being said, my opinion rarely matter :stuck_out_tongue:

Even in the case you mention, for adding a category to a post, I would think you would use "past.category = category", or the "post.category_id = category.id" method -- neither method would cause the post to save until you called "post.save".

However, if you were to call "category.post_ids = post.id", it would immediately save the post -- now "post.save" is not required. Oh wait! If the category was a NEW category it wouldn't save the post and now you would need to call "post.save".

The inconsistent behavior makes it hard for me to use this very cool method. Not a lot of people chiming in so sw0rdfish, I'm thinking my opinion matters even less!

Thanks, Tom

Same thing though.... saving a category doesn't necessarily mean I need to save every post... so you have to choose the option that is less stressful... imagine a category with 10,000 posts.... updating the category would require you to save 10,000 posts...

same with any parent-child relationship...

I haven't played with it in awhile, so I can comment specifically on your example with calling category.post_ids = post.id auto saving it, unless you're calling it during a create call... to me that would seem incorrect...

That being said, post.category_ids is the way it would need to be done... because the posts are assigned the category... in this case calling that SHOULD NOT save the post, and should require me to save it manutally.....

if I do post.create( params[:post] ) and one of the params is category_ids[ 1,4,6] then on the create the post is saved.... if I'm in the middle of am action and go post.category_ids = 1,2,3 then it SHOULD NOT save until I call post.save

I think I just confused myself.

That isn't exactly how it works. If you have a category with 10,000 posts, you would use the method "category.posts << post". This has the same inconsistency that if the category is an existing category, the post is immediately saved. If the category is a new category, the post will not be saved until either you call "category.save" or "post.save".

In a parent-child relationship, the parent will automatically save the child if the child is added to the child collection. If the parent is unsaved, it stays associated with the parent until the parent is saved. Since you can't always save the child, it would seem to be more consistent to always wait to save the child until either the parent or the child is explicitly saved. My two cents!

Thanks, Tom

yeah I see what you're saying now...

I've run into it a few times where changes aren't saved, and it turns out to be as a result of what you mention....

Fair enough argument.... you should bring it up to the big boys up top. DHH, Rick or James or someone...

It does make sense.