2011-10-02 164 views
2

快速的问题。如果我有一个模型,比如慈善机构,它具有start_dateend_date属性,我如何将其设置为控制器中的方法的current_charity基于时间的Rails实例变量?

我知道我必须做某种Charities.find(params[:something]),并且将只需要设置current_charity等于一个是start_date为> =当前的日期,以及是谁的end_date是< =当前日期(只有一次一个“当前”)。我通常只是通过params [:id]找到一个模型,所以这对我来说是新的。

谢谢!

回答

5

在模型中添加范围方法:

def self.current 
    now = Time.now 
    where("start_date <= ? AND ? <= end_date", now, now).first 
end 

然后在你的控制器:

current_charity = Charity.current 
+4

我喜欢Thilo的回答比我的好。但一定要写很多单元测试!基于时间的逻辑非常棘手,很容易错过边缘情况。你可以用一个“模拟时钟”测试时间 - 在RSpec中,你可以做一些类似'Time.stub!(:now).and_return {Time.parse(“2010-01-01 12:00”)}'来欺骗你的代码认为这是不同的一天。 – AlexChaffee

1

快速回答:搜索end_date为零的慈善机构。

较长的答案:您的数据模型可能与您所需的语义不匹配。在我看来,start_date在这里是不相关的 - 是不是目前的慈善机构end_date尚未发生?

一般来说,获取最新X的一种方法是获取所有X,按降序排序,并取第一个X(或以SQL语言,使用LIMIT 1)。在ActiveRecord的,它是这样的:

Charity.order("end_date DESC").first 

虽然我在我的Rails有点生疏3 AR语法,我不认为查询将解决您最实际的问题(尽管它看起来很酷,amirite?)。

另一个解决方案是反规范化 - 增加一个current布尔字段,和一个before_save滤波器,基于您所描述的逻辑将self[:current]。编辑:其实,这不会在这里工作,因为时间流逝,什么是当前将改变个人模型的数据范围之外。

我最好的建议是写很多单元测试!基于时间的逻辑非常棘手,很容易错过边缘情况。

0

记住要在数据库中添加索引为你会经常使用的搜索栏。

通过添加数据库迁移来添加索引。