Рельсы обновляют атрибуты без сохранения?


есть ли альтернатива 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 333

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= (они одинаковые)

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

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

Source:
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

еще один чит sheet:
http://www.davidverhasselt.com/set-attributes-in-activerecord/#cheat-sheet

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

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

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

attributes=(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 в Rails 3. attributes= проверит, что переданный ему аргумент является хэшем, и немедленно возвращает его, если это не так;assign_attributes не имеет такой проверки хэша. Смотрите ActiveRecord Attribute Assignment API documentation for attributes=.

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

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

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

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

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

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

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

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

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

рельсы 4

В Rails 4, attributes= - это просто псевдоним assign_attributes. Смотрите ActiveRecord Attribute Assignment API documentation for attributes=.

С рельсами 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.