Сохранить изменения в ассоциации has_many ТОЛЬКО при успешном сохранении родительского объекта? - PullRequest
8 голосов
/ 06 ноября 2010

Предположим, каждый Project has_many Tasks.

Если я делаю

some_project.tasks = list_of_tasks
some_project.save

Задачи проекта обновляются даже в случае сбоя сохранения. Если list_of_tasks состоит из новых записей, задачи проекта удаляются , даже если сохранение не удается! Вау!

Если сохранение не удалось, у проекта должны быть те же задачи, что и перед тем, как я начал с ним связываться. Как я могу получить это поведение и почему это не по умолчанию?

Ответы [ 4 ]

8 голосов
/ 06 ноября 2010

Заключите операторы в транзакцию:

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

Метод save! выдает исключение при ошибке, которое откатывает любые изменения, внесенные в список задач.

Вы можете прочитать документация , если вы хотите глубже погрузиться в тему.

3 голосов
/ 15 апреля 2011

Вы можете обнаружить, что функция AutosaveAssociation делает то, что вам нужно.

class Project < ActiveRecord::Base
  has_many :tasks, :autosave => true
end

Это должно автоматически обернуть сохранение в транзакции.

3 голосов
/ 14 апреля 2011

Я полагаю, что acceptpts_nested_attributes_for () обеспечит необходимое поведение

class Project < ActiveRecord::Base
  accepts_nested_attributes_for :tasks
end

Это должно обернуть все внутри транзакции. Затем вам нужно построить форму, которая будет заполнять задачи соответственно. Метод tasks_attributes в модели вашего проекта вызывается вместо метода tasks. См. API для получения дополнительной информации.

0 голосов
/ 06 ноября 2010

Перед звонком #save вы можете спросить, если some_project#valid?.Это помогает решить проблему, если сохранение не удается из-за того, что some_project является неверной записью, но не является исчерпывающим решением.

Что касается поведения Rails по умолчанию, это имеет смысл.Сказать some_project.tasks = list_of_tasks все равно что сказать «удалить все существующие задачи из some_project и назначить эти новые».Вы отбрасываете ссылку на существующий массив ассоциаций и назначаете новую.Это отражается ActiveRecord в БД.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...