From 2606fb339797a99c50e531105fc92071cef3db01 Mon Sep 17 00:00:00 2001 From: Bogdan Gusiev 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 attributes=. - 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 assign_attributes. 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 From a225d4bec51778d99ccba5f0d6700dd00d2474f4 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Fri, 23 Jan 2015 14:51:59 -0700 Subject: =?UTF-8?q?=E2=9C=82=EF=B8=8F=20and=20=F0=9F=92=85=20for=20#10776?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Minor style changes across the board. Changed an alias to an explicit method declaration, since the alias will not be documented otherwise. --- .../lib/active_record/attribute_assignment.rb | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/attribute_assignment.rb b/activerecord/lib/active_record/attribute_assignment.rb index e283db0386..e368fdfff9 100644 --- a/activerecord/lib/active_record/attribute_assignment.rb +++ b/activerecord/lib/active_record/attribute_assignment.rb @@ -22,22 +22,10 @@ module ActiveRecord 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). - # - # If the passed hash responds to permitted? method and the return value - # of this method is +false+ an ActiveModel::ForbiddenAttributesError - # exception is raised. - # - # cat = Cat.new(name: "Gorby", status: "yawning") - # cat.attributes # => { "name" => "Gorby", "status" => "yawning", "created_at" => nil, "updated_at" => nil} - # cat.assign_attributes(status: "sleeping") - # cat.attributes # => { "name" => "Gorby", "status" => "sleeping", "created_at" => nil, "updated_at" => nil } - # - # New attributes will be persisted in the database when the object is saved. - # - # Aliased to assign_attributes. - alias attributes= assign_attributes + # Alias for `assign_attributes`. See +ActiveModel::AttributeAssignment+ + def attributes=(attributes) + assign_attributes(attributes) + end private -- cgit v1.2.3