Когда я буду использовать save!, create! и update_attributes! в Rails?

Я пытаюсь выяснить, когда использовать взрыв! версии для сохранения и обновления записей? Я читал и слышал, что вам они не нужны, если вы просто сохраняете одну запись или обновляете один атрибут, если вы уверены, что ничего не должно идти не так, или всегда использовать их вне контроллера. Наверное, я параноик о том, что несколько вещей сохраняются, а затем что-то не получается, тогда в базе данных есть неполные данные. Текущий проект Rails, над которым я работаю, более 50% завершен и в настоящее время не содержит каких-либо ошибок. У меня есть некоторые пользовательские методы, которые я вызываю в моделях, которые обновляют или создают несколько записей и беспокоятся, если они должны быть в какой-то транзакции.

Извините, если это кажется разбросанным, но я просто пытаюсь понять, как правильно использовать возможности сохранения в ActiveRecord и сделать мою жизнь проще и немного больше свободного от стресса в конце. Спасибо за ваше время.

Ответ 1

Как правило, вы хотите использовать версии non-bang в своих контроллерах. Это позволяет логику следующим образом:

def update
  @model = Model.find params[:id]
  if @model.update_attributes params[:model] #returns true of false
     # handle success
  else
     # handle failure
  end
end

Я часто использую версии bang в тестах, когда хочу убедиться, что знаю, что что-то не проверяет и не сохраняется. Я определенно потратил время на отладку тестов, которые терпели неудачу из-за измененной проверки модели, что было бы очевидно, если бы я использовал версии bang.

например.

it "should do something" do
   m = Model.create! :foo => 'bar' # will raise an error on validation failure             
   m.should do_something
end

Что касается отсутствия недопустимых данных в базе данных, вы должны обрабатывать это с помощью проверки ActiveRecord (например, validates_presence_of :user_id) или определять свой собственный метод validate в модели. (http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html) Это должно предотвратить сохранение, если ваши данные недействительны. Если вы действительно параноик, вы можете добавить некоторые ограничения в свою базу данных. Проверьте документы ActiveRecord::Migration на то, как настроить уникальные индексы и другие ограничения базы данных в ваших миграциях.

Также, по моему опыту, вы хотите избежать использования каких-либо пользовательских методов сохранения или создания, когда это возможно. Если вы повторно реализуете функциональность, включенную в ActiveRecord, вы в конечном итоге платите цену по дороге. http://matthewpaulmoore.com/post/5190436725/ruby-on-rails-code-quality-checklist имеет больше сказать об этом.

Ответ 2

Основное различие заключается в том, как обрабатываются неудачные сэйвы. При обновлении класса ActiveRecord версия ! вызывает исключение, если запись недействительна.

Я рекомендую прочитать документы здесь - http://api.rubyonrails.org/classes/ActiveRecord/Base.html

Использование транзакций может также быть чем-то стоящим в поиске - http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html