Rails: update_attribute vs update_attributes
Object.update_attribute(:only_one_field, "Some Value")
Object.update_attributes(:field1 => "value", :field2 => "value2", :field3 => "value3")
Оба из них будут обновлять объект без необходимости явно указывать AR для обновления.
API Rails говорит:
для update_attribute
Обновляет один атрибут и сохраняет запись без прохождения обычной процедуры проверки достоверности. Это особенно полезно для булевых флагов в существующих записях. Обычный метод update_attribute в Base заменяется на это, когда модуль валидации смешан, в котором он по умолчанию.
для update_attributes
Обновляет все атрибуты из переданного хэша и сохраняет запись. Если объект недействителен, сохранение завершится неудачно и будет возвращено значение false.
Итак, если я не хочу, чтобы объект был проверен, я должен использовать update_attribute. Что делать, если у меня есть это обновление на before_save, будет ли он stackoverflow?
Мой вопрос: update_attribute также обходит перед сохранением или просто проверку.
Кроме того, что такое правильный синтаксис для передачи хэша update_attributes... проверьте мой пример вверху.
Ответы
Ответ 1
Обратитесь к update_attribute
. При нажатии на ссылку show source вы получите следующий код
# File vendor/rails/activerecord/lib/active_record/base.rb, line 2614
2614: def update_attribute(name, value)
2615: send(name.to_s + '=', value)
2616: save(false)
2617: end
и теперь отсылайте update_attributes
и посмотрите на свой код, который вы получаете
# File vendor/rails/activerecord/lib/active_record/base.rb, line 2621
2621: def update_attributes(attributes)
2622: self.attributes = attributes
2623: save
2624: end
разница между двумя update_attribute
использует save(false)
тогда как update_attributes
использует save
или вы можете сказать save(true)
.
Извините за длинное описание, но то, что я хочу сказать, важно. save(perform_validation = true)
, если perform_validation
является ложным, он обходит (пропуски будут правильным словом) все validations, связанный с save
.
Для второго вопроса
Кроме того, что такое правильный синтаксис для передачи хэша update_attributes... проверьте мой пример вверху.
Ваш пример верный.
Object.update_attributes(:field1 => "value", :field2 => "value2", :field3 => "value3")
или
Object.update_attributes :field1 => "value", :field2 => "value2", :field3 => "value3"
или если вы получите все данные полей и имя в хеше, скажите params[:user]
здесь используйте только
Object.update_attributes(params[:user])
Ответ 2
Совет: update_attribute
устаревает в Rails 4 через Commit a7f4b0a1. Он удаляет update_attribute
в пользу update_column
.
Ответ 3
update_attribute
Этот метод обновляет отдельный атрибут объекта без активации проверки на основе модели.
obj = Model.find_by_id(params[:id])
obj.update_attribute :language, "java"
update_attributes
Этот метод обновляет несколько атрибутов одного объекта, а также проверяет основанную на модели модель.
attributes = {:name => "BalaChandar", :age => 23}
obj = Model.find_by_id(params[:id])
obj.update_attributes(attributes)
Надеюсь, что этот ответ будет проясняться, когда использовать какой метод активной записи.
Ответ 4
Также стоит отметить, что при update_attribute
, требуемый атрибут, который необходимо обновить, не должен быть белым, указанным с помощью attr_accessible
, чтобы обновить его, а не метод массового присвоения update_attributes
, который будет обновлять только attr_accessible
указанные атрибуты.
Ответ 5
update_attribute
просто обновляет только один атрибут модели, но мы можем передать несколько атрибутов в методе update_attributes
.
Пример:
user = User.last
#update_attribute
user.update_attribute(:status, "active")
Он проходит проверку
#update_attributes
user.update_attributes(first_name: 'update name', status: "active")
он не обновляется, если проверка не выполняется.
Ответ 6
Отличные ответы.
обратите внимание, что как для ruby 1.9 и выше вы могли бы (и я думаю, должен) использовать новый синтаксис хэша для update_attributes:
Model.update_attributes(column1: "data", column2: "data")
Ответ 7
Возможно, вас заинтересует посещение этого блога, касающегося всех возможных способов назначения атрибута или записи обновления (обновлено до Rails 4) update_attribute, update, update_column, update_columns etc.
Http://www.davidverhasselt.com/set-attributes- in-activerecord/. Например, он отличается такими аспектами, как выполнение проверок, касание объекта updated_at или запуск обратных вызовов.
В качестве ответа на вопрос OP update_attribute
не update_attribute
обратные вызовы.
Ответ 8
update_attribute
и update_attributes
похожи, но
с одной большой разницей: update_attribute
не выполняет проверки.
также:
-
update_attribute
используется для обновления записи с помощью одного атрибута.
Model.update_attribute(:column_name, column_value1)
-
update_attributes
используется для обновления записи несколькими атрибутами.
Model.update_attributes(:column_name1 => column_value1, :column_name2 => column_value2, ...)
Эти два метода очень легко путать, учитывая их похожие имена и работы. Поэтому update_attribute
удаляется в пользу update_column
.
Теперь в Rails4 вы можете использовать Model.update_column(:column_name, column_value)
в месте Model.update_attribute(:column_name, column_value)
Нажмите здесь, чтобы получить дополнительную информацию о update_column
.
Ответ 9
Чтобы ответить на ваш вопрос, update_attribute
пропускает предварительно сохраненные "проверки", но он по-прежнему запускает любые другие обратные вызовы, такие как after_save
и т.д. Поэтому, если вы действительно хотите "просто обновить столбец и пропустить любое AR-Cruft", то вам нужно использовать (очевидно)
Model.update_all(...)
см. fooobar.com/questions/28854/...
Ответ 10
Недавно я столкнулся с update_attribute
vs. update_attributes
и ошибкой проверки, поэтому похожие имена, так что разные поведения, так запутались.
Чтобы передать хэш на update_attribute
и выполнить проверку байпаса, вы можете сделать:
object = Object.new
object.attributes = {
field1: 'value',
field2: 'value2',
field3: 'value3'
}
object.save!(validate: false)
Ответ 11
Я думаю, ваш вопрос в том, что если update_attribute в before_save приведет к бесконечному циклу (из вызовов update_attribute в before_save обратные вызовы, изначально вызванные вызовом update_attribute)
Я уверен, что он обходит обратный вызов before_save, поскольку он фактически не сохраняет запись. Вы также можете сохранить запись без запуска проверки с помощью
Model.save false