如何处理非模型Rails表单中的日期字段?

我正在创建一个非模型对象,它将通过使用ActiveModel与Rails表单构建器一起使用。 这是一个Rails 3项目。 这是我到目前为止的一个例子:

 class SalesReport include ActiveModel::Validations include ActiveModel::Conversion extend ActiveModel::Naming attr_accessor :promotion_code, :start_date, :end_date def initialize(attributes = {}) attributes.each do |name, value| send("#{name}=", value) end end def persisted? false end end 

我碰巧使用HAML和simple_form,但这并不重要。 最后,我只是使用标准的Rails日期选择字段:

 = simple_form_for [:admin, @report], as: :report, url: admin_reports_path do |f| = f.input :promotion_code, label: 'Promo Code' = f.input :start_date, as: :date = f.input :end_date, as: :date = f.button :submit 

Rails将日期字段拆分为单独的字段,因此在提交表单时,实际上提交了3个日期字段:

 { "report" => { "start_date(1i)" => "2014", "start_date(2i)" => "4", "start_date(3i)" => "1" } } 

在我的SalesReport对象中,我将params分配给我的attr方法,但是我得到一个错误,我没有start_date(1i)=方法,我显然没有定义。 最后,我想最终得到一个Date对象,我可以使用它而不是3个单独的字段。

我应该如何处理非模型对象中的这些日期字段?

在初始化中,您可以手动将属性中的值分配给类方法,然后在下面覆盖start_dateend_date setter方法。

 class SalesReport include ActiveModel::Validations include ActiveModel::Conversion extend ActiveModel::Naming attr_accessor :promotion_code, :start_date, :end_date def initialize(attributes = {}) @promotion_code = attributes['promotion_code'] year = attributes['start_date(1i)'] month = attributes['start_date(2i)'] day = attributes['start_date(3i)'] self.start_date = [year, month, day] end def start_date=(value) if value.is_a?(Array) @start_date = Date.new(value[0].to_i, value[1].to_i, value[2].to_i) else @start_date = value end end def persisted? false end end 

这应该允许您为setter赋予Date实例或具有单独日期元素的Array ,并且setter将为@start_date指定正确的日期。 为@end_date做同样的@end_date

希望这可以帮到你。