aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib/active_model
diff options
context:
space:
mode:
authorBogdan Gusiev <agresso@gmail.com>2015-01-23 13:57:34 +0200
committerBogdan Gusiev <agresso@gmail.com>2015-01-23 23:43:22 +0200
commit2606fb339797a99c50e531105fc92071cef3db01 (patch)
tree9de175ae320de5487adb4d32bb29c3894529805b /activemodel/lib/active_model
parent139c232b075da940cdf1042dcaad4c3b514908c9 (diff)
downloadrails-2606fb339797a99c50e531105fc92071cef3db01.tar.gz
rails-2606fb339797a99c50e531105fc92071cef3db01.tar.bz2
rails-2606fb339797a99c50e531105fc92071cef3db01.zip
Extracted `ActiveRecord::AttributeAssignment` to `ActiveModel::AttributesAssignment`
Allows to use it for any object as an includable module.
Diffstat (limited to 'activemodel/lib/active_model')
-rw-r--r--activemodel/lib/active_model/attribute_assignment.rb64
1 files changed, 64 insertions, 0 deletions
diff --git a/activemodel/lib/active_model/attribute_assignment.rb b/activemodel/lib/active_model/attribute_assignment.rb
new file mode 100644
index 0000000000..36ddbad826
--- /dev/null
+++ b/activemodel/lib/active_model/attribute_assignment.rb
@@ -0,0 +1,64 @@
+require 'active_support/core_ext/hash/keys'
+
+module ActiveModel
+ module AttributeAssignment
+ include ActiveModel::ForbiddenAttributesProtection
+
+ # Allows you to set all the attributes by passing in a hash of attributes with
+ # keys matching the attribute names.
+ #
+ # If the passed hash responds to <tt>permitted?</tt> method and the return value
+ # of this method is +false+ an <tt>ActiveModel::ForbiddenAttributesError</tt>
+ # exception is raised.
+ #
+ # class Cat
+ # include ActiveModel::AttributeAssignment
+ # attr_accessor :name, :status
+ # end
+ #
+ # cat = Cat.new
+ # cat.assign_attributes(name: "Gorby", status: "yawning")
+ # cat.name # => 'Gorby'
+ # cat.status => 'yawning'
+ # cat.assign_attributes(status: "sleeping")
+ # cat.name # => 'Gorby'
+ # cat.status => 'sleeping'
+ def assign_attributes(new_attributes)
+ if !new_attributes.respond_to?(:stringify_keys)
+ raise ArgumentError, "When assigning attributes, you must pass a hash as an argument."
+ end
+ return if new_attributes.blank?
+
+ attributes = new_attributes.stringify_keys
+ _assign_attributes(sanitize_for_mass_assignment(attributes))
+ end
+
+ private
+ def _assign_attributes(attributes)
+ attributes.each do |k, v|
+ _assign_attribute(k, v)
+ end
+ end
+
+ def _assign_attribute(k, v)
+ public_send("#{k}=", v)
+ rescue NoMethodError
+ if respond_to?("#{k}=")
+ raise
+ else
+ raise UnknownAttributeError.new(self, k)
+ end
+ end
+
+ # Raised when unknown attributes are supplied via mass assignment.
+ class UnknownAttributeError < NoMethodError
+ attr_reader :record, :attribute
+
+ def initialize(record, attribute)
+ @record = record
+ @attribute = attribute
+ super("unknown attribute '#{attribute}' for #{@record.class}.")
+ end
+ end
+ end
+end