Rails将日期范围保存到数据库

时间:2013-04-05 16:02:36

标签: ruby-on-rails

我有一个表单字段,以“05/14/2013 - 05/22/2013”​​格式发布日期范围。我的模型有两个单独的日期字段beginend,用于表单字段中的相应开始日期和结束日期。将日期范围纳入正确的字段的最佳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的更改在创建和验证记录时不会显示。

2 个答案:

答案 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_attributescreate等批量分配方法。如果您已在模型中定义了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

这是处理数据库结构和用户输入表单之间差异的最佳方法。