【问题标题】:ActiveRecord: issue with 'find' method when querying datesActiveRecord:查询日期时出现“查找”方法的问题
【发布时间】:2010-05-26 22:33:04
【问题描述】:

我正在为在 SQLite3 数据库上运行的 ActiveRecord 模型上的“查找”方法中的日期查询条件而苦苦挣扎。我的模型如下:

Day:
  failure_day:   date
  failure_count: integer 

当我尝试查询 Days 时,我得到以下信息(仅限伪代码):

Query:   Days.all
Result:  [{failure_day: 2010-04-14, failure_count: 1}]

Query:   Days.find(:first, :conditions=>'failure_day > 2010-02-01')
Result:  {failure_day: 2010-04-14, failure_count: 1}

Query:   Days.find(:first, :conditions=>'failure_day = 2010-04-14')
Result:  nil

Query:   Days.find(:first, :conditions=>'failure_day < 2010-05-05')
Result:  nil

我不明白为什么最后两个查询返回“nil”。第一个查询 (Days.all) 证明我的数据库中有一条记录。第二个正确地将 'failure_day' 与小于 'failure_day' 的日期匹配,但是当尝试等于或小于它时不起作用。

有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails ruby activerecord


    【解决方案1】:

    您只提供了伪代码,这使得它变得更加困难。

    您告诉我们您的 failure_date 列是 DATE 类型。让 ActiveRecord 为您处理细节:

    Day.all(:conditions => {:failure_date => Date.today})
    Day.all(:conditions => ["failure_date < ?", Date.today])
    Day.all(:conditions => {:failure_date => Date.new(1900, 1, 1) .. 5.days.ago})
    

    【讨论】:

    • 我同意这应该有效,但由于某种原因它没有。我得到一条记录: Day.all('SELECT * FROM "days" WHERE (failure_day ["failure_day ["failure_day
    • 您使用的是什么版本的 ActiveRecord、SQLite、Ruby?发布会话要点,我们可以在其中查看您在控制台中输入的代码以及 development.log 中的内容
    • 由于需要格式化,我已经在上面发布了对您评论的答案。
    • 感谢您提供有关查看日志的提示。我对 Rails 还很陌生,还没有看过日志,真的很有用。
    【解决方案2】:

    你应该使用

    Days.find(:first, :conditions=>["DATE_FORMAT(failure_day, '%Y-%m-%d') > '2010-02-01'"])
    
    Days.find(:first, :conditions=>["DATE_FORMAT(failure_day, '%Y-%m-%d') = '2010-04-14'"])
    
    Days.find(:first, :conditions=>["DATE_FORMAT(failure_day, '%Y-%m-%d') < '2010-05-05'"])
    

    【讨论】:

    • 好吧..看起来可行。如果我要比较一个实际的日期对象(:conditions => ["failure_day=?", my_date]) 会怎样。我还需要 DATE_FORMAT 吗?
    【解决方案3】:

    这是 François Beausoleil 对 cme​​ts 的回答: “您使用的是什么版本的 ActiveRecord、SQLite、Ruby?发布一个会话的要点,我们可以在其中看到您在控制台输入的代码以及 development.log 中的内容”

    我把它放在这里是因为我无法在评论中格式化,如果没有格式化,这篇文章将几乎无法阅读!

    SQLite version:       3.6.12
    ActiveRecord version: 2.3.5
    

    测试代码:

    require 'test_helper'
    
    class StatTest < ActiveSupport::TestCase
      test "Tmp" do
        # Prints: [#<Day id: 980190962, failure_day: "2010-04-14" ... >]
        p Day.all
    
        # Prints: []
        p Day.all(:conditions=>["failure_day < ?", '2010-05-14'])
    
        # Prints: []
        p Day.all(:conditions=>["failure_day < ?", Date.new(2010,5,4)])
      end
    end
    

    测试日志

    Day Load (0.3ms)   SELECT * FROM "days" 
    Day Load (0.1ms)   SELECT * FROM "days" WHERE (failure_day < '2010-05-14') 
    Day Load (0.1ms)   SELECT * FROM "days" WHERE (failure_day < '2010-05-04') 
    

    直接从 SQLite 运行任何这些命令都会返回预期的行,因此问题不在于 ActiveRecord 生成的 SQLite 命令。奇怪。

    【讨论】:

    • 在上面的测试中,您没有生成任何记录。您知道测试在单独的数据库中运行吗?因此,如果您不创建任何实例(或让夹具为您生成实例),则预计不会有任何记录。
    • 宾果游戏!是的,我知道固定装置以及测试在不同数据库上运行的事实。我还验证了夹具正在加载数据(通过“p Day.all”命令返回记录)。问题在于,在夹具中,我将 failure_day 定义为 'failure_day: 2010/04/14',Rails 将其转换为字符串。将其更改为 'failure_day: 2010-04-14' 并且夹具将数据加载为日期并且所有三个查询都有效!感谢您帮助激发这些想法。
    【解决方案4】:

    感谢François Beausoleil 的探究性问题,我能够找出问题所在。 François 提醒我测试从测试装置加载数据(在我的例子中是 test/fixtures/days.yml)。我已经设置了这个,但我想我最好仔细检查一下格式。在我发现的 days.yml 文件中:

    one:
      failure_day:   2010/04/14
      failure_count: 1
    

    注意到日期没有像测试中那样定义为 2010-04-14,所以我将其更改为:

    one:
      failure_day:   2010-04-14
      failure_count: 1
    

    现在所有查询都可以工作了!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多