【问题标题】:Rails ActiveRecord Find / Search by DateRails ActiveRecord 按日期查找/搜索
【发布时间】:2012-10-24 02:19:39
【问题描述】:

我正在尝试按“created_at”日期查找记录 - 数据库列类型为“日期时间”并且 我正在使用来自 jQuery 的 UI DatePicker

我的网址如下所示:“localhost:3000/users_supported?selected_date=2012-10-31”

到目前为止,我做得很好 :) 我在控制器中的查询如下所示:

@support_histories = current_agent.support_histories.where(:created_at => Date.parse(params[:selected_date]))

如何仅从“日期时间”数据库列中按“日期”正确提取记录

我尝试在 Rails 控制台中执行此操作,但没有运气:

sh = SupportHistory.where(:created_at => DateTime.parse('2012-10-31'))
sh = SupportHistory.where(:created_at => Date.parse('2012-10-31'))
sh = SupportHistory.where(:created_at => DateTime.strptime('2012-10-31', '%Y-%m-%d'))

如果我确实喜欢下面提到的,我得到了记录,但这对我没有用,因为我试图按“日期”而不是“日期时间”来查找记录

sh = SupportHistory.where(:created_at => '2012-10-31 19:49:57')

【问题讨论】:

    标签: activerecord ruby-on-rails-3.2


    【解决方案1】:

    如果要解析特定的日期时间

    SupportHistory.where("created_at>=?", DateTime.parse('10 Dec 2021 11:54:00 PST -08:00'))
    

    【讨论】:

      【解决方案2】:

      您当前的查询不起作用,因为您正在查询 datetime 列上的 date。这是两种不同的数据类型。

      对于日期时间列,您需要一个日期时间过滤器。您可以通过将 DateTime 对象传递给 where 子句来做到这一点。但是,在您的情况下,您需要一整天的记录,因此您需要指定 00:00:0023:59:59 之间的范围。

      Rails 5.1 之前:

      SupportHistory.where(created_at: date.beginning_of_day..date.end_of_day)
      

      Rails 5.1 及更高版本:(这将使用 #all_day 生成完全相同的范围)

      SupportHistory.where(created_at: date.all_day)
      

      【讨论】:

        【解决方案3】:

        我有时使用的一个简单解决方案是将日期(时间)字段转换为数据库中的文本,而不是在应用程序端将字符串解析为日期。对于您的情况:

        where('CAST(created_at AS text) LIKE ?', params[:selected_date])
        

        在数据库上可能不是最有效的(取决于您使用它的上下文),但在应用程序端节省了很多 pita。

        【讨论】:

          【解决方案4】:

          我通过在模型中创建一个方法来解决这个问题,如下所示, 说,我的模型是ticket.rb

           def created_date
             self.created_at.to_date
           end
          

          然后我这样查询,

           selected_date = Date.parse(params[:date])
          
           Ticket.all.map{|t| t if t.created_date == selected_date}.compact
          

          这为我提供了与用户选择的日期相匹配的准确结果。

          【讨论】:

          • 这不是一个好方法,因为“Ticket.all”会获取表中的所有票证并将它们扩展为内存中的数组。不利于内存消耗和性能。此外,不要先执行“map”,然后执行“compact”(很可能循环遍历整个票证集合两次!),只需使用“select”方法,该方法一次过滤集合。但最后,Jason Noble 上面的回答是正确的做法,因为“where”不会像“all”那样将所有内容扩展到内存中。
          【解决方案5】:
          selected_date = Date.parse(params[:selected_date])
          # This will look for records on the given date between 00:00:00 and 23:59:59
          sh = SupportHistory.where(
                 :created_at => selected_date.beginning_of_day..selected_date.end_of_day)
          

          时区可能是您需要考虑的问题,但如果您的所有时间都在同一个时区,这应该可以工作。

          【讨论】:

          • 我没有话要感谢你,但我不得不说我爱你 ;) - 我是编码新手,一整天都在尝试这样做 :) 我仍然想知道 - 有吗一种查询数据库不包括时间的方法?
          • guides.rubyonrails.org/active_record_querying.html 的第 2.2.2 节与我给出的答案相似。你可能会做一些有创意的事情,比如select("date(created_at) as ordered_date).where(:ordered_date => ____),但我喜欢beginning_of_day..end_of_day 解决方案。
          • 这是一个优雅的 Railsy 解决方案。 :)
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-03
          • 1970-01-01
          • 1970-01-01
          • 2016-01-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多