Rails update_attributes без сохранения?
Есть ли альтернатива 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 ответа
Я верю, что вы ищете 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
Ты можешь использовать assign_attributes
или же attributes=
(они одинаковы)
Методы обновления шпаргалки (для Rails 4):
update_attributes
знак равноassign_attributes
+save
attributes=
= псевдонимassign_attributes
update
= псевдонимupdate_attributes
Источник:
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/
Вы можете использовать метод "атрибутов":
@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
Для массового присвоения значений модели ActiveRecord без сохранения используйте либо assign_attributes
или же attributes=
методы. Эти методы доступны в Rails 3 и новее. Тем не менее, есть небольшие различия и связанные с версией ошибки, о которых следует знать.
Оба метода следуют этому использованию:
@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }
@user.attributes = { model: "Sierra", year: "2012", looks: "Sexy" }
Обратите внимание, что ни один из методов не будет выполнять проверки или выполнять обратные вызовы; обратные вызовы и проверка произойдет, когда save
называется.
Рельсы 3
attributes=
немного отличается от assign_attributes
в рельсах 3. attributes=
проверит, что переданный ему аргумент является Hash, и немедленно возвращает, если это не так; 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=
,
Рельсы 4
В Rails 4 attributes=
это просто псевдоним assign_attributes
, См. Документацию API назначения атрибутов ActiveRecord дляattributes=
,
В Rails 4 любой метод может использоваться взаимозаменяемо. Неспособность передать Hash в качестве первого аргумента приведет к очень полезному исключению: ArgumentError: When assigning attributes, you must pass a hash as an argument.
Validations
Если вы предварительно выполняете задания в подготовке к save
Вы также можете быть заинтересованы в проверке перед сохранением. Вы можете использовать valid?
а также invalid?
методы для этого. Оба возвращают логические значения. valid?
возвращает true, если несохраненная модель прошла все проверки, или false, если нет. invalid?
просто обратная сторона valid?
valid?
можно использовать так:
@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }.valid?
Это даст вам возможность обрабатывать любые вопросы проверки до вызова save
,