From 2606fb339797a99c50e531105fc92071cef3db01 Mon Sep 17 00:00:00 2001
From: Bogdan Gusiev <agresso@gmail.com>
Date: Fri, 23 Jan 2015 13:57:34 +0200
Subject: Extracted `ActiveRecord::AttributeAssignment` to
 `ActiveModel::AttributesAssignment`

Allows to use it for any object as an includable module.
---
 .../lib/active_record/attribute_assignment.rb      | 57 ++++++++--------------
 activerecord/lib/active_record/errors.rb           | 16 ++----
 2 files changed, 23 insertions(+), 50 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/attribute_assignment.rb b/activerecord/lib/active_record/attribute_assignment.rb
index bf64830417..e283db0386 100644
--- a/activerecord/lib/active_record/attribute_assignment.rb
+++ b/activerecord/lib/active_record/attribute_assignment.rb
@@ -3,7 +3,24 @@ require 'active_model/forbidden_attributes_protection'
 module ActiveRecord
   module AttributeAssignment
     extend ActiveSupport::Concern
-    include ActiveModel::ForbiddenAttributesProtection
+    include ActiveModel::AttributeAssignment
+
+    def _assign_attributes(attributes) # :nodoc:
+      multi_parameter_attributes  = {}
+      nested_parameter_attributes = {}
+
+      attributes.each do |k, v|
+        if k.include?("(")
+          multi_parameter_attributes[k] = attributes.delete(k)
+        elsif v.is_a?(Hash)
+          nested_parameter_attributes[k] = attributes.delete(k)
+        end
+      end
+      super(attributes)
+
+      assign_nested_parameter_attributes(nested_parameter_attributes) unless nested_parameter_attributes.empty?
+      assign_multiparameter_attributes(multi_parameter_attributes) unless multi_parameter_attributes.empty?
+    end
 
     # Allows you to set all the attributes by passing in a hash of attributes with
     # keys matching the attribute names (which again matches the column names).
@@ -19,47 +36,11 @@ module ActiveRecord
     #
     # New attributes will be persisted in the database when the object is saved.
     #
-    # Aliased to <tt>attributes=</tt>.
-    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
-      multi_parameter_attributes  = []
-      nested_parameter_attributes = []
-
-      attributes = sanitize_for_mass_assignment(attributes)
-
-      attributes.each do |k, v|
-        if k.include?("(")
-          multi_parameter_attributes << [ k, v ]
-        elsif v.is_a?(Hash)
-          nested_parameter_attributes << [ k, v ]
-        else
-          _assign_attribute(k, v)
-        end
-      end
-
-      assign_nested_parameter_attributes(nested_parameter_attributes) unless nested_parameter_attributes.empty?
-      assign_multiparameter_attributes(multi_parameter_attributes) unless multi_parameter_attributes.empty?
-    end
-
+    # Aliased to <tt>assign_attributes</tt>.
     alias attributes= assign_attributes
 
     private
 
-    def _assign_attribute(k, v)
-      public_send("#{k}=", v)
-    rescue NoMethodError
-      if respond_to?("#{k}=")
-        raise
-      else
-        raise UnknownAttributeError.new(self, k)
-      end
-    end
-
     # Assign any deferred nested attributes after the base attributes have been set.
     def assign_nested_parameter_attributes(pairs)
       pairs.each { |k, v| _assign_attribute(k, v) }
diff --git a/activerecord/lib/active_record/errors.rb b/activerecord/lib/active_record/errors.rb
index fc28ab585f..d710d96a9a 100644
--- a/activerecord/lib/active_record/errors.rb
+++ b/activerecord/lib/active_record/errors.rb
@@ -178,18 +178,10 @@ module ActiveRecord
   class DangerousAttributeError < ActiveRecordError
   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.to_s
-      super("unknown attribute '#{attribute}' for #{@record.class}.")
-    end
-
-  end
+  UnknownAttributeError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new( # :nodoc:
+    'ActiveRecord::UnknownAttributeError', 
+    'ActiveModel::AttributeAssignment::UnknownAttributeError'
+  )
 
   # Raised when an error occurred while doing a mass assignment to an attribute through the
   # +attributes=+ method. The exception has an +attribute+ property that is the name of the
-- 
cgit v1.2.3