validation_context & update_attributes - PullRequest
       22

validation_context & update_attributes

4 голосов
/ 06 декабря 2011

Как я могу указать validation_context с update_attributes?

Я могу сделать это, используя 2 операции (без update_attributes):

my_model.attributes = { :name => '123', :description => '345' }
my_model.save(:context => :some_context)

1 Ответ

6 голосов
/ 03 февраля 2015

Нет способа сделать это, вот код для update_attributes (который является псевдонимом для update)

def update(attributes)
  with_transaction_returning_status do
    assign_attributes(attributes)
    save
  end
end

Как вы можете видеть, просто назначьте данные атрибуты и сохраните без передачилюбой аргумент метода save.

Эти операции заключены в блок, переданный в with_transaction_returning_status, чтобы избежать проблем, когда некоторые назначения изменяют данные в ассоциациях.Таким образом, безопаснее заключать эти операции при вызове вручную.

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

def strict_update(attributes)
  with_transaction_returning_status do
    assign_attributes(attributes)
    save(context: :strict)
  end
end

Вы можете улучшить его, добавив update_with_context справа от вашего ApplicationRecord (базовый класс для всех моделей в Rails 5).Итак, ваш код будет выглядеть так:

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  # Update attributes with validation context.
  # In Rails you can provide a context while you save, for example: `.save(:step1)`, but no way to
  # provide a context while you update. This method just adds the way to update with validation
  # context.
  #
  # @param [Hash] attributes to assign
  # @param [Symbol] validation context
  def update_with_context(attributes, context)
    with_transaction_returning_status do
      assign_attributes(attributes)
      save(context: context)
    end
  end
end
...