我正在使用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个单独的字段。
我应该如何处理非模型对象中的这些日期字段?
答案 0 :(得分:4)
在初始化过程中,您可以手动将属性值分配给类方法,然后在下面覆盖start_date
和end_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
这应该允许您为设置者提供具有单独日期元素的Date
实例或Array
,并且设置者会将正确的日期分配给@start_date
。
对@end_date
执行相同的操作。
希望这可以帮到你。