我有一个表单字段,以“05/14/2013 - 05/22/2013”格式发布日期范围。我的模型有两个单独的日期字段begin
和end
,用于表单字段中的相应开始日期和结束日期。将日期范围纳入正确的字段的最佳MVC方法是什么?
我一直试图在控制器的create
方法中手动解构日期范围,但看起来在创建记录之前模型中没有正确显示更新的参数。
编辑: 日期范围以这种格式出现,因为我使用的是Keith Wood的日期选择,它在单个输入字段中输出日期。
我目前正在尝试做的是(contract
是我的模型的名称,dates
是输入日期范围:
beginDate = params[:dates].split("-")[0].strip()
endDate = params[:dates].split("-")[1].strip()
params.delete :dates
params[:contract][:begin] = Date.strptime(beginDate, '%m/%d/%Y')
params[:contract][:end] = Date.strptime(endDate, '%m/%d/%Y')
@contract = Contract.new(params[:contract])
...但是这些对params的更改在创建和验证记录时不会显示。
答案 0 :(得分:5)
在模型上定义一个setter,它接受该字段,将其拆分,并将每个部分放入相应的字段中。
def date_range=(val)
begin_str, end_str = val.split(' - ')
self.begin_at = Date.parse(begin_str)
self.end_at = Date.parse(end_str)
end
这可以直接调用,也可以使用update_attributes
或create
等批量分配方法。如果您已在模型中定义了date_range
,请确保将attr_accessible
(或相关的参数名称)添加到begin
。
我在示例中更改了字段名称,因为end
和{{1}}应该避免作为字段名称,因为一个是方法而另一个是ruby语法的一部分。
答案 1 :(得分:1)
您可以使用虚拟属性将日期范围文本转换为模型级别的各个日期。在模型中添加如下所示的setter和getter,
def date_range_text
return "#{start_date.to_s} - #{end_date.to_s}"
end
def date_range_text= val
start_date_text,end_date_text = val.split[" - "]
start_date = Time.zone.parse(start_date_text) unless start_date_text.nil?
end_date = Time.zone.parse(end_date_text) unless end_date_text.nil?
end
在表单中使用data_range_text。有关我的信息,请查看下面的railscast。
http://railscasts.com/episodes/16-virtual-attributes-revised
这是处理数据库结构和用户输入表单之间差异的最佳方法。