lib/active_attr/mass_assignment.rb
require "active_attr/chainable_initialization"
require "active_support/concern"
module ActiveAttr
# MassAssignment allows you to bulk set and update attributes
#
# Including MassAssignment into your model gives it a set of mass assignment
# methods, similar to those found in ActiveRecord.
#
# @example Usage
# class Person
# include ActiveAttr::MassAssignment
# end
#
# @since 0.1.0
module MassAssignment
extend ActiveSupport::Concern
include ChainableInitialization
# Mass update a model's attributes
#
# @example Assigning a hash
# person.assign_attributes(:first_name => "Chris", :last_name => "Griego")
# person.first_name #=> "Chris"
# person.last_name #=> "Griego"
#
# @param [Hash{#to_s => Object}, #each] new_attributes Attributes
# used to populate the model
# @param [Hash, #[]] options Options that affect mass assignment
#
# @option options [Symbol] :as (:default) Mass assignment role
# @option options [true, false] :without_protection (false) Bypass mass
# assignment security if true
#
# @since 0.1.0
def assign_attributes(new_attributes, options={})
sanitized_new_attributes = sanitize_for_mass_assignment_if_sanitizer new_attributes, options
sanitized_new_attributes.each do |name, value|
writer = "#{name}="
send writer, value if respond_to? writer
end if sanitized_new_attributes
end
# Mass update a model's attributes
#
# @example Assigning a hash
# person.attributes = { :first_name => "Chris", :last_name => "Griego" }
# person.first_name #=> "Chris"
# person.last_name #=> "Griego"
#
# @param (see #assign_attributes)
#
# @since 0.1.0
def attributes=(new_attributes)
assign_attributes new_attributes
end
# Initialize a model with a set of attributes
#
# @example Initializing with a hash
# person = Person.new(:first_name => "Chris", :last_name => "Griego")
# person.first_name #=> "Chris"
# person.last_name #=> "Griego"
#
# @param (see #assign_attributes)
#
# @since 0.1.0
def initialize(attributes=nil, options={})
assign_attributes attributes, options
super
end
private
# @since 0.8.0
def sanitize_for_mass_assignment_if_sanitizer(new_attributes, options={})
if new_attributes && !options[:without_protection] && respond_to?(:sanitize_for_mass_assignment, true)
sanitize_for_mass_assignment_with_or_without_role new_attributes, options
else
new_attributes
end
end
# Rails 3.0 and 4.0 do not take a role argument for the sanitizer
# @since 0.7.0
def sanitize_for_mass_assignment_with_or_without_role(new_attributes, options)
if method(:sanitize_for_mass_assignment).arity.abs > 1
sanitize_for_mass_assignment new_attributes, options[:as] || :default
else
sanitize_for_mass_assignment new_attributes
end
end
end
end