validation_context & update_attributes
Asked Answered
H

1

6

How can I specify validation_context with update_attributes ?

I can do that using 2 operations (without update_attributes):

my_model.attributes = { :name => '123', :description => '345' }
my_model.save(:context => :some_context)
Hydracid answered 6/12, 2011 at 9:7 Comment(0)
Q
18

There's no way to do that, here's the code for update_attributes (which is an alias for update)

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

As you can see it just assign the given attributes and save without passing any argument to the save method.

These operations are enclosed into a block passed to with_transaction_returning_status to prevent issues where some assignements modify data in associations. So you're safer enclosing those operations when called manually.

One simple trick is to add context dependent public method to your model like this:

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

You can improve it by adding update_with_context right to your ApplicationRecord (base class for all models in Rails 5). So your code will look like this:

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
Quiz answered 2/2, 2015 at 21:2 Comment(1)
Thank you for this. It's exactly what I was looking for.Sacramental

© 2022 - 2024 — McMap. All rights reserved.