Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save changes to a has_many association ONLY when you successfully save the parent object?

Suppose each Project has_many Tasks.

If I do

some_project.tasks = list_of_tasks
some_project.save

The project's tasks get updated even if the save fails. If list_of_tasks consists of new records, the project's tasks get deleted even if the save fails! WHOA!

If the save fails, the project should have the same tasks it had before I started messing with it. How do I get this behavior and why isn't it the default?

like image 304
Tom Lehman Avatar asked Nov 06 '10 01:11

Tom Lehman


2 Answers

Enclose the statements in a transaction:

Project.transaction do
  p.tasks = task_list
  p.save!
end

The save! method throws an exception upon error, which rolls back any changes done to task list.

You can read the documentation if you want to dive a bit more deeply on the subject.

like image 191
Harish Shetty Avatar answered Sep 22 '22 05:09

Harish Shetty


I believe that accepts_nested_attributes_for() will provide the behavior you want:

class Project < ActiveRecord::Base
  accepts_nested_attributes_for :tasks
end

This should wrap everything inside a transaction. You then need to build the form that populates the tasks accordingly. The method tasks_attributes in your Project model is called instead of the tasks method. See the API for more information.

like image 37
adamlamar Avatar answered Sep 22 '22 05:09

adamlamar