2010-05-25 77 views
0

我在通过SQLite3数据库运行的ActiveRecord模型上的'find'方法中查询日期的条件而挣扎。我的模型如下:ActiveRecord:在查询日期时使用'find'方法问题

Day: 
    failure_day: date 
    failure_count: integer 

当我尝试查询日子里,我得到以下(只有伪代码):

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 

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

任何想法?

回答

0

你应该使用

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'"]) 
+0

好吧..看起来可行。如果我比较实际的日期对象(:conditions => [“failure_day =?”,my_date]),那么怎么办?我还需要DATE_FORMAT吗? – 2010-05-25 14:11:42

3

你仅供伪代码,这使得它更难。

您告诉我们您的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}) 
+0

我同意这应该工作,但由于某种原因它不。 我得到一个记录: 一天。全部('SELECT * FROM“days”WHERE(failure_day <\''2010-05-14''') 没有记录: Day.all(:conditions => [“failure_day <?”,'2010- 04-14' ]) 如果我故意语法错误: Day.all(:条件=> [ “failure_day < '?'”, '2010-05-14']) 我得到一个错误: 语法错误:SELECT * FROM“days”WHERE(failure_day <'''2010-05-14'') 很明显,它试图执行正确的SQL(除了多余的引号外,与第一个示例完全相同),但它不会没有使用明确的SQL工作!到底是怎么回事??! – 2010-05-25 22:39:07

+0

你使用的是什么版本的ActiveRecord,SQLite,Ruby?发布一个会议的主题,我们可以看到您在控制台输入的代码以及开发中的内容.log – 2010-05-26 02:39:01

+0

由于需要格式化,我已在上面发布了对您的评论的答案。 – 2010-05-26 08:10:38

0

这是一个答案,由弗朗索瓦博索莱伊的意见:?,红宝石您使用 “的ActiveRecord,SQLite的什么版本发布会议的要点,我们可以请参阅您在控制台输入的代码以及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 

test.log中

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的返回预期行的,所以这个问题是不是与SQLite的命令ActiveRecord正在生成。离奇。

+0

在上面的测试中,您不会生成任何记录。你知道那个测试在一个单独的数据库中运行吗?因此,如果您没有创建任何实例(或者有固定设备为您生成实例),则预计没有任何记录。 – 2010-05-26 13:35:43

+0

宾果!是的,我知道夹具和测试在不同的数据库上运行的事实。我还验证了夹具正在加载数据(通过'p Day.all'命令返回记录)。问题是,在夹具中,我将failure_day定义为'failure_day:2010/04/14',Rails正在将其转换为字符串。将其更改为'failure_day:2010-04-14',夹具将数据加载为日期,并且所有三个查询都可以工作!感谢您的帮助,激发了这些想法。 – 2010-05-26 14:28:05

0

感谢François Beausoleil的探究性问题,我能够弄清楚什么是错的。弗朗索瓦提醒我测试从测试装置中加载数据(在我的例子中是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 

所有查询工作!