Когда я использую save !, создать! и update_attributes! в рельсах? - PullRequest
60 голосов
/ 19 ноября 2009

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

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

Ответы [ 3 ]

74 голосов
/ 19 ноября 2009

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

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

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

51 голосов
/ 19 ноября 2009

Как правило, вы хотите использовать не-взрывные версии в ваших контроллерах. Это позволяет логику так:

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

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

, например

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 голосов
/ 14 марта 2019

Что! (bang) означает для update_attributes и save:

«Возбудить исключение при неудаче», а не «Вернуть ложь при неудаче»

https://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update-21 https://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-save

Что! (Взрыв) означает для create это:

«Вызывать исключение при сбое», а не «Возвращать полученный объект при сбое» https://api.rubyonrails.org/classes/ActiveRecord/Persistence/ClassMethods.html#method-i-create-21

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