DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world
Multi-part Parameter Extractor
For those times when you want to get a date object out of the multi-part parameters without having to do a mass assignment to a model object. I extracted this code directly from AR so I think it should be pretty solid but I have not tested it so your mileage may vary.
Take the following and place it into your application helper or whatever helper you'd like. To use it you simply pass in an instance of the object on which the multi-part parameter exists. This is so that the type to instantiate can be reflected from the column information. Then you specify the attribute name of the parameter you're looking to create from the next parameter which is the hash containing the multi-part parameter value.
example:
for a form containing dude[birth_date] you'd call the method like this:
extract_date(@the_dude, 'birth_date', params[:dude])
def extract_date(parent_object, param_name, atts)
atts.stringify_keys!
multi_parameter_attributes = []
atts.each do |k, v|
multi_parameter_attributes << [ k, v ] if k.include?(param_name+"(")
end
attributes = { }
for pair in multi_parameter_attributes
multiparameter_name, value = pair
attribute_name = multiparameter_name.split("(").first
attributes[attribute_name] = [] unless attributes.include?(attribute_name)
unless value.empty?
attributes[attribute_name] <<
[ find_parameter_position(multiparameter_name), type_cast_attribute_value(multiparameter_name, value) ]
end
end
attributes.each { |name, values| attributes[name] = values.sort_by{ |v| v.first }.collect { |v| v.last } }
errors = []
result = nil
attributes.each do |name, values|
klass = (parent_object.class.reflect_on_aggregation(name.to_sym) || parent_object.column_for_attribute(name)).klass
result = Time == klass ? klass.local(*values) : klass.new(*values)
end
return result
end
def find_parameter_position(multiparameter_name)
multiparameter_name.scan(/\(([0-9]*).*\)/).first.first
end
def type_cast_attribute_value(multiparameter_name, value)
multiparameter_name =~ /\([0-9]*([a-z])\)/ ? value.send("to_" + $1) : value
end





