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