2011-10-30 5 views
0

UserモデルとGroupモデルがあります。 User belongs_to GroupGroupの属性はcheck_minutesです。Rails:n分前のすべてのユーザーを検索する方法。nは結合グループに格納されます。

ユーザモデルにoldfreshという2つのスコープを作成したいとします。古いユーザーはcreated_atのユーザーがuser.group.check_minutes.agoより古いユーザーです。新鮮なユーザーはのユーザーがuser.group.check_minutes.agoより新しい。

私はスコープを書いた:

scope :old, joins(:group).where("`users`.`created_at` <= 
     DATE_SUB(NOW(), INTERVAL `groups`.`check_minutes` MINUTE)") 
    scope :fresh, joins(:group).where("`users`.`created_at` > 
     DATE_SUB(NOW(), INTERVAL `groups`.`check_minutes` MINUTE)") 

そしてスペック:

describe "scopes" do 
    let(:group) {Group.make :check_minutes => 20} 
    let(:old_user) {User.make :group => group, :created_at => 30.minutes.ago} 
    let(:new_user) {User.make :group => group, :created_at => 10.minutes.ago} 

    context "#fresh" do 
     it "should scope all new users" do 
     User.fresh.should eq([ new_user ]) 
     end 
    end 
    context "#old" do 
     it "should scope all old users" do 
     User.old.should eq([ old_user ]) 
     end 
    end 
    end 

仕様は、(oldのために、それはOKです)freshに失敗:間違って何

expected [#<User id: 7967, ... >] 
     got [] 

!どのように私のスコープ\ specsをうまく動作させるには?

スコープを整理するには、より良い方法がわかっているといいでしょう。

答えて

2

スコープはOKです。

問題は、データベースの設定されたタイムゾーンに関係なく、RailsがデータベースにUTC時刻の値を格納し、ORMの実行中にそれらをあなたの(Rails)タイムゾーンに変換することです。

...あなたのスコープがであることを意味します。 OK - 'Rails'の現在の時間をクエリに挿入するだけで済みます。 http://leonid.shevtsov.me/ru/time-now-vs-time-zone-now-in:SO上ロシアの記事をリンクするために申し訳ありませんが、私は私のブログでこれをカバーしている

scope :old, lambda { joins(:group).where(["`users`.`created_at` <= 
    DATE_SUB(?, INTERVAL `groups`.`check_minutes` MINUTE)", Time.zone.now]) } 
scope :fresh, lambda { joins(:group).where(["`users`.`created_at` > 
    DATE_SUB(?, INTERVAL `groups`.`check_minutes` MINUTE)", Time.zone.now]) } 
+0

-rails –

+0

本当にいいです、+1 – apneadiving

+0

ありがとう!できます。記事は非常に便利です! Спасибо:) – petRUShka

関連する問題