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,

Другие вопросы по тегам