ActiveRecordのscopeの中でTime.nowを使ったときに起こる問題

model の中で scope を使うときに今の時間を比較してレコードをとってきたい場合に時間が固まってしまうことがある
developmentモードでは起こらずproductionモードのみで起こる。
今日登録したユーザーを表示したいとなった場合

class User < ActiveRecord::Base
  scope :today_scope, where("users.created_at BETWEEN :start_time AND :end_time", { start_time: Time.now.beginning_of_day, end_time: Time.now.end_of_day })
end
        

上記をproductionモードで走らせると起動した時間でTime.nowが固まってしまうため、ずっと起動しっぱなしで次の日になった場合正確な情報はとれない
正確な情報を取る場合はlambdaを使う

class User < ActiveRecord::Base
  scope :today_scope, lambda{ where("users.created_at BETWEEN :start_time AND :end_time", { start_time: Time.now.beginning_of_day, end_time: Time.now.end_of_day })}
end
        

これで今日登録したユーザーはとってこれる。

ちなみに以下のソースでも固まってしまうので注意が必要

class User < ActiveRecord::Base
  DISABLE = 0
  ACTIVE = 1
  

  scope :today_scope, lambda{ where("users.created_at BETWEEN :start_time AND :end_time", { start_time: Time.now.beginning_of_day, end_time: Time.now.end_of_day })}
  scope :active, today_scope.where(status: User::ACTIVE)
end
        
 @users = User.active.all
        

activeのscopeにlambdaがついていない状態でtoday_scopeを使うとtoday_scopeのlambdaは有効にならず時間が固まってしまう。

class User < ActiveRecord::Base
  DISABLE = 0
  ACTIVE = 1
  

  scope :today_scope, lambda{ where("users.created_at BETWEEN :start_time AND :end_time", { start_time: Time.now.beginning_of_day, end_time: Time.now.end_of_day })}
  scope :active, lambda{ today_scope.where(status: User::ACTIVE) }
end

activeにもlambdaを使うことによって時間は固まらなくなる
lambdaは->で書いた方が見やすいと思うので->を使った方がいいと思う