Included Modules

Files

Class Index [+]

Quicksearch

ActiveRecord::AttributeAssignment

Public Instance Methods

assign_attributes(new_attributes, options = {}) click to toggle source

Allows you to set all the attributes for a particular mass-assignment security role by passing in a hash of attributes with keys matching the attribute names (which again matches the column names) and the role name using the :as option.

To bypass mass-assignment security you can use the :without_protection => true option.

  class User < ActiveRecord::Base
    attr_accessible :name
    attr_accessible :name, :is_admin, :as => :admin
  end

  user = User.new
  user.assign_attributes({ :name => 'Josh', :is_admin => true })
  user.name       # => "Josh"
  user.is_admin?  # => false

  user = User.new
  user.assign_attributes({ :name => 'Josh', :is_admin => true }, :as => :admin)
  user.name       # => "Josh"
  user.is_admin?  # => true

  user = User.new
  user.assign_attributes({ :name => 'Josh', :is_admin => true }, :without_protection => true)
  user.name       # => "Josh"
  user.is_admin?  # => true
    # File lib/active_record/attribute_assignment.rb, line 66
66:     def assign_attributes(new_attributes, options = {})
67:       return if new_attributes.blank?
68: 
69:       attributes = new_attributes.stringify_keys
70:       multi_parameter_attributes = []
71:       nested_parameter_attributes = []
72:       @mass_assignment_options = options
73: 
74:       unless options[:without_protection]
75:         attributes = sanitize_for_mass_assignment(attributes, mass_assignment_role)
76:       end
77: 
78:       attributes.each do |k, v|
79:         if k.include?("(")
80:           multi_parameter_attributes << [ k, v ]
81:         elsif respond_to?("#{k}=")
82:           if v.is_a?(Hash)
83:             nested_parameter_attributes << [ k, v ]
84:           else
85:             send("#{k}=", v)
86:           end
87:         else
88:           raise(UnknownAttributeError, "unknown attribute: #{k}")
89:         end
90:       end
91: 
92:       # assign any deferred nested attributes after the base attributes have been set
93:       nested_parameter_attributes.each do |k,v|
94:         send("#{k}=", v)
95:       end
96: 
97:       @mass_assignment_options = nil
98:       assign_multiparameter_attributes(multi_parameter_attributes)
99:     end
attributes=(new_attributes) click to toggle source

Allows you to set all the attributes at once by passing in a hash with keys matching the attribute names (which again matches the column names).

If any attributes are protected by either attr_protected or attr_accessible then only settable attributes will be assigned.

  class User < ActiveRecord::Base
    attr_protected :is_admin
  end

  user = User.new
  user.attributes = { :username => 'Phusion', :is_admin => true }
  user.username   # => "Phusion"
  user.is_admin?  # => false
    # File lib/active_record/attribute_assignment.rb, line 33
33:     def attributes=(new_attributes)
34:       return unless new_attributes.is_a?(Hash)
35: 
36:       assign_attributes(new_attributes)
37:     end

Protected Instance Methods

mass_assignment_options() click to toggle source
     # File lib/active_record/attribute_assignment.rb, line 103
103:     def mass_assignment_options
104:       @mass_assignment_options ||= {}
105:     end
mass_assignment_role() click to toggle source
     # File lib/active_record/attribute_assignment.rb, line 107
107:     def mass_assignment_role
108:       mass_assignment_options[:as] || :default
109:     end

Private Instance Methods

assign_multiparameter_attributes(pairs) click to toggle source

Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done by calling new on the column type or aggregation type (through composed_of) object with these parameters. So having the pairs written_on(1) = “2004”, written_on(2) = “6”, written_on(3) = “24”, will instantiate written_on (a date type) with Date.new(“2004”, “6”, “24”). You can also specify a typecast character in the parentheses to have the parameters typecasted before they’re used in the constructor. Use i for Fixnum, f for Float, s for String, and a for Array. If all the values for a given attribute are empty, the attribute will be set to nil.

     # File lib/active_record/attribute_assignment.rb, line 120
120:     def assign_multiparameter_attributes(pairs)
121:       execute_callstack_for_multiparameter_attributes(
122:         extract_callstack_for_multiparameter_attributes(pairs)
123:       )
124:     end
execute_callstack_for_multiparameter_attributes(callstack) click to toggle source
     # File lib/active_record/attribute_assignment.rb, line 134
134:     def execute_callstack_for_multiparameter_attributes(callstack)
135:       errors = []
136:       callstack.each do |name, values_with_empty_parameters|
137:         begin
138:           send(name + "=", read_value_from_parameter(name, values_with_empty_parameters))
139:         rescue => ex
140:           errors << AttributeAssignmentError.new("error on assignment #{values_with_empty_parameters.values.inspect} to #{name}", ex, name)
141:         end
142:       end
143:       unless errors.empty?
144:         raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes"
145:       end
146:     end
extract_callstack_for_multiparameter_attributes(pairs) click to toggle source
     # File lib/active_record/attribute_assignment.rb, line 197
197:     def extract_callstack_for_multiparameter_attributes(pairs)
198:       attributes = { }
199: 
200:       pairs.each do |pair|
201:         multiparameter_name, value = pair
202:         attribute_name = multiparameter_name.split("(").first
203:         attributes[attribute_name] = {} unless attributes.include?(attribute_name)
204: 
205:         parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
206:         attributes[attribute_name][find_parameter_position(multiparameter_name)] ||= parameter_value
207:       end
208: 
209:       attributes
210:     end
extract_max_param_for_multiparameter_attributes(values_hash_from_param, upper_cap = 100) click to toggle source
     # File lib/active_record/attribute_assignment.rb, line 193
193:     def extract_max_param_for_multiparameter_attributes(values_hash_from_param, upper_cap = 100)
194:       [values_hash_from_param.keys.max,upper_cap].min
195:     end
find_parameter_position(multiparameter_name) click to toggle source
     # File lib/active_record/attribute_assignment.rb, line 216
216:     def find_parameter_position(multiparameter_name)
217:       multiparameter_name.scan(/\(([0-9]*).*\)/).first.first.to_i
218:     end
instantiate_time_object(name, values) click to toggle source
     # File lib/active_record/attribute_assignment.rb, line 126
126:     def instantiate_time_object(name, values)
127:       if self.class.send(:create_time_zone_conversion_attribute?, name, column_for_attribute(name))
128:         Time.zone.local(*values)
129:       else
130:         Time.time_with_datetime_fallback(self.class.default_timezone, *values)
131:       end
132:     end
read_date_parameter_value(name, values_hash_from_param) click to toggle source
     # File lib/active_record/attribute_assignment.rb, line 174
174:     def read_date_parameter_value(name, values_hash_from_param)
175:       return nil if (1..3).any? {|position| values_hash_from_param[position].blank?}
176:       set_values = [values_hash_from_param[1], values_hash_from_param[2], values_hash_from_param[3]]
177:       begin
178:         Date.new(*set_values)
179:       rescue ArgumentError # if Date.new raises an exception on an invalid date
180:         instantiate_time_object(name, set_values).to_date # we instantiate Time object and convert it back to a date thus using Time's logic in handling invalid dates
181:       end
182:     end
read_other_parameter_value(klass, name, values_hash_from_param) click to toggle source
     # File lib/active_record/attribute_assignment.rb, line 184
184:     def read_other_parameter_value(klass, name, values_hash_from_param)
185:       max_position = extract_max_param_for_multiparameter_attributes(values_hash_from_param)
186:       values = (1..max_position).collect do |position|
187:         raise "Missing Parameter" if !values_hash_from_param.has_key?(position)
188:         values_hash_from_param[position]
189:       end
190:       klass.new(*values)
191:     end
read_time_parameter_value(name, values_hash_from_param) click to toggle source
     # File lib/active_record/attribute_assignment.rb, line 161
161:     def read_time_parameter_value(name, values_hash_from_param)
162:       # If Date bits were not provided, error
163:       raise "Missing Parameter" if [1,2,3].any?{|position| !values_hash_from_param.has_key?(position)}
164:       max_position = extract_max_param_for_multiparameter_attributes(values_hash_from_param, 6)
165:       # If Date bits were provided but blank, then return nil
166:       return nil if (1..3).any? {|position| values_hash_from_param[position].blank?}
167: 
168:       set_values = (1..max_position).collect{|position| values_hash_from_param[position] }
169:       # If Time bits are not there, then default to 0
170:       (3..5).each {|i| set_values[i] = set_values[i].blank? ? 0 : set_values[i]}
171:       instantiate_time_object(name, set_values)
172:     end
read_value_from_parameter(name, values_hash_from_param) click to toggle source
     # File lib/active_record/attribute_assignment.rb, line 148
148:     def read_value_from_parameter(name, values_hash_from_param)
149:       klass = (self.class.reflect_on_aggregation(name.to_sym) || column_for_attribute(name)).klass
150:       if values_hash_from_param.values.all?{|v|v.nil?}
151:         nil
152:       elsif klass == Time
153:         read_time_parameter_value(name, values_hash_from_param)
154:       elsif klass == Date
155:         read_date_parameter_value(name, values_hash_from_param)
156:       else
157:         read_other_parameter_value(klass, name, values_hash_from_param)
158:       end
159:     end
type_cast_attribute_value(multiparameter_name, value) click to toggle source
     # File lib/active_record/attribute_assignment.rb, line 212
212:     def type_cast_attribute_value(multiparameter_name, value)
213:       multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
214:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.