日期比较如何在ActiveRecord中运行?

时间:2012-05-01 09:43:41

标签: ruby-on-rails ruby activerecord

我是Rail的新手并尝试在ActiveRecord中进行查询。我试图获得所有状态为“Landed”的记录,这些记录已超过60天。我的查询可以使所有项目的状态为“Landed”。当我添加“created_at<?”的最后一个条件时,我总是得到一个空关系。我知道我有适合该描述的项目,所以我在查询中做错了什么并且不明白。我相信我的错误是在日期比较中,但我不确定。

1. Projects
    belongs_to :status
    has_many :project_status_histories
2. Status
    has_many :projects
    has_many :project_status_histories
3. Project_Status_Histories
    belongs_to :status
    belongs_to :project

Project.find(:all, :joins => [:project_status_histories, :status], :conditions => {:projects => {:status_id => Status.where(:name => 'Landed').first.id }, :project_status_histories => {:created_at => ["created_at < ?", (Date.today - 60.days)]}})

我尝试使用dbconsole逐步构建查询,但没有运气。在此先感谢您的所有帮助。

2 个答案:

答案 0 :(得分:4)

我不认为这是日期算术。一个很好的方法是使用命名范围。将以下内容添加到project.rb:

scope :landed, joins(:status).where('statuses.name' => 'Landed')
scope :recent, lambda \
              { joins(:project_status_histories) \
              .where('project_status_histories.created_at < ?', Date.today - 60.days) } 

然后您可以使用以下方法检索相关记录/对象

Project.landed.recent

这在我的测试中对我有用。您还应该查看导轨指南,我从中偷走了大部分内容:

http://guides.rubyonrails.org/active_record_querying.html#scopes

答案 1 :(得分:0)

您的查询有点复杂......

我宁愿这样做:

Project.where("status.name = ? AND project_status_histories.created_at < ?", "Landed", Time.now.day - 60.days)

我认为这应该会更好。让我知道如果没有,也许我写错了,不幸的是我现在无法测试...

[编辑]

您可能还想查看生成的SQL是什么,使用“explain”方法,只需将其添加到查询的末尾并打印结果,例如使用您的查询:

Project.find(:all, :joins => [:project_status_histories, :status], :conditions => {:projects => {:status_id => Status.where(:name => 'Landed').first.id }, :project_status_histories => {:created_at => ["created_at < ?", (Date.today - 60.days)]}}).explain