После следования советам Бенуа я придумал нечто подобное, используя виртуальные атрибуты.На стороне просмотра есть 3 отдельных элемента select (year, mon, day) внутри поля fields_for.Данные передаются в массовое назначение контроллера (без изменений в контроллере, см. asciicasts # 16 ) и затем передаются получателю / установщику (то есть виртуальному атрибуту) в модели.Я использую Rails 3.0.3 и simpleForm для кода представления.
В представлении:
<%= f.label "Design Date", :class=>"float_left" %>
<%= f.input :design_month, :label => false, :collection => 1..12 %>
<%= f.input :design_day, :label => false, :collection => 1..31 %>
<%= f.input :design_year, :label => false, :collection => 1900..2020 %>
В модели:
validate :design_date_validator
def design_year
design_date.year
end
def design_month
design_date.month
end
def design_day
design_date.day
end
def design_year=(year)
if year.to_s.blank?
@design_date_errors = true
else
self.design_date = Date.new(year.to_i,design_date.month,design_date.day)
end
end
def design_month=(month)
if month.to_s.blank?
@design_date_errors = true
else
self.design_date = Date.new(design_date.year,month.to_i,design_date.day)
end
end
def design_day=(day)
if day.to_s.blank?
@design_date_errors = true
else
self.design_date = Date.new(design_date.year,design_date.month,day.to_i)
end
end
#validator
def design_date_validator
if @design_date_errors
errors.add(:base, "Design Date Is invalid")
end
end
'design_date_attr' - это виртуальный атрибут, который устанавливает значение design_date в базе данных.Получатель передает обратно хэш, аналогичный тому, который передается в форме.Сеттер проверяет наличие пробелов, создает новый объект даты и устанавливает его, а также устанавливает переменную ошибки.Пользовательский валидатор: design_date_validator проверяет переменную экземпляра ошибки и устанавливает переменную ошибок.Я использовал ': base', потому что имя переменной было нечитаемым, а использование base удаляет это значение из строки ошибки.
Несколько вещей, которые необходимо изменить для рефакторинга, могут быть переменной экземпляра проверки ошибок, но, по-видимому, она работает по крайней мере.Если кто-нибудь знает лучший способ обновить объекты Date, я бы хотел это услышать.