开发者

Rails Time.now, shows time server started and not actual time

I've seen this problem before but I'm not sure how to solve it.

Say I h开发者_开发知识库ave:

class Notification < ActiveRecord::Base
  scope :current_notifications, where("starts_at <= ?", Time.now).where("ends_at >= ?", Time.now).limit(1)
end

So the scope is being calculated from the time that the server started, any thoughts on how to fix instances like this?


You need a lambda. (This creates an anonymous method, which Rails then calls each time the scope is called.)

class Notification < ActiveRecord::Base
  scope :current_notifications, lambda {
    now = Time.now
    where("starts_at <= ?", now).where("ends_at >= ?", now).limit(1)
  }
end


On development your models are reloaded with each request. On production they are cached, so the scope will refer to Time.now as it was when the model was first loaded into memory.

Get round this using a lambda expression. The lambda expression will be evaluated each time the scope is used.

You can also dry up your relation a little using a named parameter to remove the repeated Time.now, as shown:

scope :current_notifications, lambda do
  where("starts_at <= :now or ends_at >= :now", now: Time.now).limit(1)
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜