Rails update_attributes без сохранения? - PullRequest
361 голосов
/ 21 июля 2011

Есть ли альтернатива update_attributes, которая не сохраняет запись?

Так что я мог бы сделать что-то вроде:

@car = Car.new(:make => 'GMC')
#other processing
@car.update_attributes(:model => 'Sierra', :year => "2012", :looks => "Super Sexy, wanna make love to it")
#other processing
@car.save

Кстати, я знаю, что могу @car.model = 'Sierra', но я хочу обновить их все в одной строке.

Ответы [ 4 ]

569 голосов
/ 02 августа 2012

Я считаю, что вы ищете assign_attributes.

Это в основном то же самое, что update_attributes, но не сохраняет запись:

class User < ActiveRecord::Base
  attr_accessible :name
  attr_accessible :name, :is_admin, :as => :admin
end

user = User.new
user.assign_attributes({ :name => 'Josh', :is_admin => true }) # Raises an ActiveModel::MassAssignmentSecurity::Error
user.assign_attributes({ :name => 'Bob'})
user.name        # => "Bob"
user.is_admin?   # => false
user.new_record? # => true
157 голосов
/ 12 сентября 2013

Вы можете использовать assign_attributes или attributes= (они одинаковые)

Обновление шпаргалки методов (для Rails 4):

  • update_attributes = assign_attributes + save
  • attributes= = псевдоним assign_attributes
  • update = псевдоним update_attributes

* Источник: 1025 *
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/persistence.rb
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_assignment.rb

Еще один шпаргалка:
http://www.davidverhasselt.com/set-attributes-in-activerecord/#cheat-sheet

63 голосов
/ 21 июля 2011

Вы можете использовать метод «атрибутов»:

@car.attributes = {:model => 'Sierra', :years => '1990', :looks => 'Sexy'}

Источник: http://api.rubyonrails.org/classes/ActiveRecord/Base.html

attribute = (new_attributes, guard_protected_attributes = true) Позволяет устанавливать все атрибуты одновременно, передавая хеш с ключами, совпадающими с именами атрибутов (которые снова совпадают с именами столбцов).

Если guard_protected_attributes имеет значение true (по умолчанию), то чувствительные атрибуты могут быть защищены от этой формы массового назначения с помощью макроса attr_protected. Или вы можете указать, какие атрибуты доступны с помощью макроса attr_accessible. Тогда все атрибуты, не включенные в это, не могут быть назначены массово.

class User < ActiveRecord::Base
  attr_protected :is_admin
end

user = User.new
user.attributes = { :username => 'Phusion', :is_admin => true }
user.username   # => "Phusion"
user.is_admin?  # => false

user.send(:attributes=, { :username => 'Phusion', :is_admin => true }, false)
user.is_admin?  # => true
8 голосов
/ 17 мая 2016

Для массового присвоения значений модели ActiveRecord без сохранения используйте методы assign_attributes или attributes=.Эти методы доступны в Rails 3 и новее.Тем не менее, есть небольшие различия и связанные с версией ошибки, о которых следует знать.

Оба метода следуют этому использованию:

@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }

@user.attributes = { model: "Sierra", year: "2012", looks: "Sexy" }

Обратите внимание, что ни один из методов не будет выполнять проверки или выполнять обратные вызовы;обратные вызовы и проверка будут происходить при вызове save.

Rails 3

attributes= немного отличается от assign_attributes в Rails 3. attributes= проверит, что аргумент передан емуявляется хешем и сразу возвращается, если нет;assign_attributes не имеет такой проверки хэша.См. API-интерфейс назначения атрибутов ActiveRecord для attributes=.

Следующий недействительный код завершится с ошибкой, просто вернувшись без установки атрибутов:

@user.attributes = [ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ]

attributes= будет вести себя тихо, как если бы назначения были выполнены успешно, тогда как на самом деле это не так.

Этот недействительный код вызовет исключение, когда assign_attributes попытается преобразовать в строку ключи хеш-функции включающего массива:

@user.assign_attributes([ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ])

assign_attributes вызовет исключение NoMethodError для stringify_keys, что указывает на то, что первый аргумент не является хэшем.Само исключение не очень информативно в отношении фактической причины, но тот факт, что исключение действительно имеет место, очень важно.

Единственное различие между этими случаями - это метод, используемый для массового присвоения:attributes= тихо завершается успешно, а assign_attributes вызывает исключение, информирующее о том, что произошла ошибка.

Эти примеры могут показаться надуманными и в некоторой степени, но этот тип ошибки может легко возникнуть при преобразованииданные из API, или даже просто используя серию преобразования данных и забывая Hash[] результаты окончательного .map.Оставьте код на 50 строк выше и удалите 3 функции из вашего назначения атрибутов, и вы получите рецепт ошибки.

Урок с Rails 3 таков: всегда использование assign_attributesвместо attributes=.

Rails 4

В Rails 4 attributes= - это просто псевдоним assign_attributes.См. API-интерфейс назначения атрибутов ActiveRecord для attributes=.

В Rails 4 любой метод может использоваться взаимозаменяемо.Неспособность передать хэш в качестве первого аргумента приведет к очень полезному исключению: ArgumentError: When assigning attributes, you must pass a hash as an argument.

Проверки

Если вы предварительно выполняете проверку назначений для save, выможет быть интересно проверить перед сохранением.Для этого вы можете использовать методы valid? и invalid?.Оба возвращают логические значения.valid? возвращает true, если несохраненная модель прошла все проверки, или false, если нет.invalid? - это просто обратное значение valid?

valid? можно использовать следующим образом:

@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }.valid?

Это даст вам возможность обрабатывать любые вопросы проверки до вызоваsave.

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