Module ActiveModel::MassAssignmentSecurity::ClassMethods
In: lib/active_model/mass_assignment_security.rb

Methods

Public Instance methods

Returns an instance of ActiveModel::MassAssignmentSecurity::WhiteList with the attributes protected by attr_accessible method. If no role is provided, then :default is used.

  class Customer
    include ActiveModel::MassAssignmentSecurity

    attr_accessor :name, :credit_rating

    attr_accessible :name, as: [:admin, :default]
    attr_accessible :credit_rating, as: :admin
  end

  Customer.accessible_attributes
  # => #<ActiveModel::MassAssignmentSecurity::WhiteList: {"name"}>

  Customer.accessible_attributes(:default)
  # => #<ActiveModel::MassAssignmentSecurity::WhiteList: {"name"}>

  Customer.accessible_attributes(:admin)
  # => #<ActiveModel::MassAssignmentSecurity::WhiteList: {"name", "credit_rating"}>
active_authorizer()

Alias for active_authorizers

Returns a hash with the protected attributes (by attr_accessible or attr_protected) per role.

  class Customer
    include ActiveModel::MassAssignmentSecurity

    attr_accessor :name, :credit_rating

    attr_accessible :name, as: [:admin, :default]
    attr_accessible :credit_rating, as: :admin
  end

  Customer.active_authorizers
  # => {
  #       :admin=> #<ActiveModel::MassAssignmentSecurity::WhiteList: {"name", "credit_rating"}>,
  #       :default=>#<ActiveModel::MassAssignmentSecurity::WhiteList: {"name"}>
  #    }

Specifies a white list of model attributes that can be set via mass-assignment.

Like attr_protected, a role for the attributes is optional, if no role is provided then :default is used. A role can be defined by using the :as option with a symbol or an array of symbols as the value.

This is the opposite of the attr_protected macro: Mass-assignment will only set attributes in this list, to assign to the rest of attributes you can use direct writer methods. This is meant to protect sensitive attributes from being overwritten by malicious users tampering with URLs or forms. If you‘d rather start from an all-open default and restrict attributes as needed, have a look at attr_protected.

  class Customer
    include ActiveModel::MassAssignmentSecurity

    attr_accessor :name, :credit_rating

    # Both admin and default user can change name of a customer
    attr_accessible :name, as: [:admin, :default]
    # Only admin can change credit rating of a customer
    attr_accessible :credit_rating, as: :admin

    def assign_attributes(values, options = {})
      sanitize_for_mass_assignment(values, options[:as]).each do |k, v|
        send("#{k}=", v)
      end
    end
  end

When using the :default role:

  customer = Customer.new
  customer.assign_attributes({ name: 'David', credit_rating: 'Excellent', last_login: 1.day.ago }, as: :default)
  customer.name          # => "David"
  customer.credit_rating # => nil

  customer.credit_rating = 'Average'
  customer.credit_rating # => "Average"

And using the :admin role:

  customer = Customer.new
  customer.assign_attributes({ name: 'David', credit_rating: 'Excellent', last_login: 1.day.ago }, as: :admin)
  customer.name          # => "David"
  customer.credit_rating # => "Excellent"

Note that using Hash#except or Hash#slice in place of attr_accessible to sanitize attributes provides basically the same functionality, but it makes a bit tricky to deal with nested attributes.

Attributes named in this macro are protected from mass-assignment whenever attributes are sanitized before assignment. A role for the attributes is optional, if no role is provided then :default is used. A role can be defined by using the :as option with a symbol or an array of symbols as the value.

Mass-assignment to these attributes will simply be ignored, to assign to them you can use direct writer methods. This is meant to protect sensitive attributes from being overwritten by malicious users tampering with URLs or forms.

  class Customer
    include ActiveModel::MassAssignmentSecurity

    attr_accessor :name, :email, :logins_count

    attr_protected :logins_count
    # Suppose that admin can not change email for customer
    attr_protected :logins_count, :email, as: :admin

    def assign_attributes(values, options = {})
      sanitize_for_mass_assignment(values, options[:as]).each do |k, v|
        send("#{k}=", v)
      end
    end
  end

When using the :default role:

  customer = Customer.new
  customer.assign_attributes({ name: 'David', email: 'a@b.com', logins_count: 5 }, as: :default)
  customer.name         # => "David"
  customer.email        # => "a@b.com"
  customer.logins_count # => nil

And using the :admin role:

  customer = Customer.new
  customer.assign_attributes({ name: 'David', email: 'a@b.com', logins_count: 5}, as: :admin)
  customer.name         # => "David"
  customer.email        # => nil
  customer.logins_count # => nil

  customer.email = 'c@d.com'
  customer.email # => "c@d.com"

To start from an all-closed default and enable attributes as needed, have a look at attr_accessible.

Note that using Hash#except or Hash#slice in place of attr_protected to sanitize attributes provides basically the same functionality, but it makes a bit tricky to deal with nested attributes.

Returns an empty array by default. You can still override this to define the default attributes protected by attr_protected method.

  class Customer
    include ActiveModel::MassAssignmentSecurity

    def self.attributes_protected_by_default
      [:name]
    end
  end

  Customer.protected_attributes
  # => #<ActiveModel::MassAssignmentSecurity::BlackList: {:name}>

Defines sanitize method.

  class Customer
    include ActiveModel::MassAssignmentSecurity

    attr_accessor :name

    attr_protected :name

    def assign_attributes(values)
      sanitize_for_mass_assignment(values).each do |k, v|
        send("#{k}=", v)
      end
    end
  end

  # See ActiveModel::MassAssignmentSecurity::StrictSanitizer for more information.
  Customer.mass_assignment_sanitizer = :strict

  customer = Customer.new
  customer.assign_attributes(name: 'David')
  # => ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes for Customer: name

Also, you can specify your own sanitizer object.

  class CustomSanitizer < ActiveModel::MassAssignmentSecurity::Sanitizer
    def process_removed_attributes(klass, attrs)
      raise StandardError
    end
  end

  Customer.mass_assignment_sanitizer = CustomSanitizer.new

  customer = Customer.new
  customer.assign_attributes(name: 'David')
  # => StandardError: StandardError

Returns an instance of ActiveModel::MassAssignmentSecurity::BlackList with the attributes protected by attr_protected method. If no role is provided, then :default is used.

  class Customer
    include ActiveModel::MassAssignmentSecurity

    attr_accessor :name, :email, :logins_count

    attr_protected :logins_count
    attr_protected :logins_count, :email, as: :admin
  end

  Customer.protected_attributes
  # => #<ActiveModel::MassAssignmentSecurity::BlackList: {"logins_count"}>

  Customer.protected_attributes(:default)
  # => #<ActiveModel::MassAssignmentSecurity::BlackList: {"logins_count"}>

  Customer.protected_attributes(:admin)
  # => #<ActiveModel::MassAssignmentSecurity::BlackList: {"logins_count", "email"}>

[Validate]