Multiparameter Attributes Handler
Background
Rails form helpers for time, datetime and date return multiparameter attributes that ActiveRecord objects are able to convert into parent attributes.
For example
date_select(:thing, :last_read)
when set to 24th June 2004, will generate
'thing' => {
"last_read(1i)" => "2004",
"last_read(2i)" => "6",
"last_read(3i)" => "24"
}
ActiveRecord understands this and converts these key/value pairs into a date object that is passed to thing.last_read=
A solution without ActiveRecord
Multiparameter Attributes Handler allows other objects to do the same.
thing_params = MultiparameterAttributesHandler.manipulate_all(params[:thing])
This creates a last_read key with a time object derived from the values
thing_params == {
"last_read(1i)" => "2004",
"last_read(2i)" => "6",
"last_read(3i)" => "24",
"last_read" => Time.local('2004', '6', '24')
}
So for a ActiveResource Thing, this functionality can be added by over-riding the attributes setter:
class Thing < ActiveResource::Base
def attributes=(params)
super MultiparameterAttributesHandler.manipulate_all(params)
end
end
However, as the params splitting and rebuilding is happening in the views and controller space, it might well make more sense to do the manipulation in the controller:
class ThingsController < ApplicationController
....
def update
@thing = Thing.find(params[:id])
@property.update_attributes thing_params
redirect_to @property
end
private
def thing_params
MultiparameterAttributesHandler.manipulate_all(params[:thing])
end
end
Only setter affected
Note that this gem provides handling of the parameters received from the form submission. For the form helpers to work, they need to passed a date or time to the form.
One solution is to override the getter in the model. So for the Thing example above:
require 'date'
class Thing < ActiveResource::Base
def last_read
Time.parse(super)
end
end
Rails form date helpers will then work for last_read:
datetime_select(:thing, :last_read)
Installation
This functionality is made available via the multiparameter_attributes_handler gem. So add this to your gemfile:
gem 'multiparameter_attributes_handler'