【问题标题】:ruby query between two date parameters两个日期参数之间的红宝石查询
【发布时间】:2014-06-05 16:52:40
【问题描述】:

我有一个名为 Result 的模型。我需要创建一个变量来返回某个日期范围之间的所有结果。在 Result 模型上有一个名为 date 的字段,在表单上,​​我将开始和结束日期作为参数捕获并将它们传递回控制器。

因此,如果用户在 startdate 参数中输入“01/01/2014”并在参数中输入“01/01/2015”,我需要返回日期在此范围之间的所有结果。

当用户按下“过滤器”按钮时,参数最终被捕获为变量 startdate 和 enddate

我试过了,但它似乎不起作用

@results = Result.where("date >= ? and date <= ?", startdate, enddate")

然后我查看了生成的 SQL 并认为它需要是这样的

@results = Result.where("date >= ? and date <= ?", '#{startdate)', '#{enddate}')

有什么想法吗?

谢谢

【问题讨论】:

  • 您的日期输入格式是否总是固定的?

标签: ruby-on-rails ruby


【解决方案1】:

正如@MrYoshiji 所建议的那样,在这种情况下您应该注意的一件事是您的startdateenddate 都是DateDateTimeTime 对象。否则,比较会失败。

1.) 一种快捷方式是将日期选择器应用到您的input 标记中。您可以在日期选择器的初始化程序中specify the format

2.) 使用date/time tag rails form helper

3.) 使用regex 以确保格式正确。

当它通过你所有的验证时,然后做:

@results = Result.where(date: Date.parse(startdate).beginning_of_day..Date.parse(enddate).end_of_day)

您还可以在末尾添加救援以确保它不会进入 500 页。

在查询的末尾添加一个rescue Result.all(在 ALL-ELSE-FAILED 的情况下)

是的,请确保您选择正确的时区。 postgresql 的默认值是 UTC。

【讨论】:

  • 那是有风险的,如果Date.parse失败了会报错
  • 他说他的参数是'01/01/2014'的形式。所以,我认为这会奏效。
  • He said his parameters 既然是参数,就意味着每个用户都发送它:“永远不要相信用户的输入”。我认为这个start_date = Date.parse(startdate) rescue Date.current 是最低限度的,最终救援时会出现一条错误消息,上面写着“无法解析日期”
【解决方案2】:

感谢大家的建议。这是我最终的解决方案。

首先,使用 datepicker 确保只能在表单中输入有效日期,如下所示...

  $(function(){
    $('#startdate').datepicker({
      changeYear: true,
      dateFormat:"dd/mm/yy",
      defaultDate: "#{Date.today.day}/#{Date.today.month}/#{Date.today.year}",
      change: function() {
        var isoDate = this.getValue('yyyy-mm-dd');
        $(this).attr('data-value', isoDate);
      }
    });
$('#enddate').datepicker({
  changeYear: true,
  dateFormat:"dd/mm/yy",
  defaultDate: "#{Date.today.day}/#{Date.today.month}/#{Date.today.year}",
  change: function() {
    var isoDate = this.getValue('yyyy-mm-dd');
    $(this).attr('data-value', isoDate);
    }
  });
});


%form{:action => employee_results_path(@employee), :class => 'navbar-search pull-left'} 
  .field
    %input{:type =>'text', :placeholder => params[:startdate] != nil ? params[:startdate] : "from date", :id => 'startdate', :name => "startdate", :style => 'width: 100px'}
    %input{:type =>'text', :placeholder => params[:startdate] != nil ? params[:enddate] : "to date", :id => 'enddate', :name => "enddate", :style => 'width: 100px'}

然后,在控制器中将参数捕获为变量并将它们解析为日期

sdate = Date.parse(params[:startdate])
edate = Date.parse(params[:enddate])

然后使用我在这个问题中收到的有用解决方案

@results = Result.where(:date => sdate..edate)

这是一种享受。感谢大家帮助我学习!

【讨论】:

    【解决方案3】:

    你可以写成

    @results = Result.where(:date => startdate..enddate)
    

    但在使用查询之前,startdateenddate 必须需要转换为Date 对象。

    【讨论】:

    • 这是我回答这个问题的关键,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    • 2011-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多