Over a million developers have joined DZone.

Multi-part Parameter Extractor

DZone's Guide to

Multi-part Parameter Extractor

· ·
Free Resource
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.

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)

      multi_parameter_attributes = []
      atts.each do |k, v|
        multi_parameter_attributes << [ k, v ] if k.include?(param_name+"(")
      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) ]

      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)

      return result
    def find_parameter_position(multiparameter_name)

    def type_cast_attribute_value(multiparameter_name, value)
      multiparameter_name =~ /\([0-9]*([a-z])\)/ ? value.send("to_" + $1) : value

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}