Module: OnForm::MultiparameterAttributes
- Included in:
- Form
- Defined in:
- lib/on_form/rails_compat.rb
Instance Method Summary collapse
-
#assign_multiparameter_attributes(pairs) ⇒ Object
Instantiates objects for all attribute classes that needs more than one constructor parameter.
- #execute_callstack_for_multiparameter_attributes(callstack) ⇒ Object
- #extract_callstack_for_multiparameter_attributes(pairs) ⇒ Object
- #find_parameter_position(multiparameter_name) ⇒ Object
- #type_cast_attribute_value(multiparameter_name, value) ⇒ Object
Instance Method Details
#assign_multiparameter_attributes(pairs) ⇒ Object
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 Integer and f for Float. If all the values for a given attribute are empty, the attribute will be set to nil.
13 14 15 16 17 |
# File 'lib/on_form/rails_compat.rb', line 13 def assign_multiparameter_attributes(pairs) execute_callstack_for_multiparameter_attributes( extract_callstack_for_multiparameter_attributes(pairs) ) end |
#execute_callstack_for_multiparameter_attributes(callstack) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/on_form/rails_compat.rb', line 19 def execute_callstack_for_multiparameter_attributes(callstack) errors = [] callstack.each do |name, values_with_empty_parameters| begin if defined?(ActiveRecord::AttributeAssignment::MultiparameterAttribute) # ActiveRecord 4.2 and below: you must use MultiparameterAttribute to construct the attribute value. # we therefore have to look up which model the attribute actually lives on. backing_model, backing_name = backing_for_attribute(name) send("#{name}=", ActiveRecord::AttributeAssignment::MultiparameterAttribute.new(backing_model, backing_name.to_s, values_with_empty_parameters).read_value) else # ActiveRecord 5.0+: you can assign the indexed hash to the column and it will construct the value for you. if values_with_empty_parameters.each_value.all?(&:nil?) values = nil else values = values_with_empty_parameters end send("#{name}=", values) end rescue => ex errors << ActiveRecord::AttributeAssignmentError.new("error on assignment #{values_with_empty_parameters.values.inspect} to #{name} (#{ex.})", ex, name) end end unless errors.empty? error_descriptions = errors.map(&:message).join(",") raise ActiveRecord::MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes [#{error_descriptions}]" end end |
#extract_callstack_for_multiparameter_attributes(pairs) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/on_form/rails_compat.rb', line 47 def extract_callstack_for_multiparameter_attributes(pairs) attributes = {} pairs.each do |(multiparameter_name, value)| attribute_name = multiparameter_name.split("(").first attributes[attribute_name] ||= {} parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value) attributes[attribute_name][find_parameter_position(multiparameter_name)] ||= parameter_value end attributes end |
#find_parameter_position(multiparameter_name) ⇒ Object
65 66 67 |
# File 'lib/on_form/rails_compat.rb', line 65 def find_parameter_position(multiparameter_name) multiparameter_name.scan(/\(([0-9]*).*\)/).first.first.to_i end |
#type_cast_attribute_value(multiparameter_name, value) ⇒ Object
61 62 63 |
# File 'lib/on_form/rails_compat.rb', line 61 def type_cast_attribute_value(multiparameter_name, value) multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value end |