2011-03-26 190 views
1

嗨,我有以下範圍:軌道範圍過濾

scope :expires_within, lambda 
{|time| where("created_at BETWEEN ? AND ?", 30.days.ago, 
                 time.from_now - 30.days)} 

它並不那麼重要,它的工作原理。

這只是給了我所有這些都在一定時間範圍內創建我的數據庫中的對象。我想要做的是過濾這個範圍,以便它刪除一些對象。

以上範圍是在一個名爲模型。我有一個名爲鎖定另一個模型,「屬於」一郵政,每個有許多。所以這意味着每個鎖上都有一個外鍵,其中有相應的Post的ID。

我想完成的是以下內容:我想過濾掉上述範圍內的帖子,其中不是有任何鎖定。所以從抽象/高級視圖:我想要得到的職位從上述範圍返回和刪除任何具有任何相關的鎖(哪怕只有一個)。

這可能嗎?我將不得不使用某種形式的複合查詢的,使用類似except?我會很感激任何幫助。

我現在有一些作品,但我有一種揮之不去的感覺,是不是很有效的,也許它可以在數據庫上通過修改上述範圍內進行,並更高效:

Post.expires_within(1.day) - Lock.all.collect { |lock| lock.post } 

所以這基本上得到崗位的集合,然後取每個鎖的帖子,並將其所有轉儲到一個數組,然後將其從原來的一套崗位減去。

回答

3

有人誰已經經歷過這個問題,是一種足以幫助我在IRC(雷達),並指出我this answer。現在我的新範圍如下:

scope :not_locked, lambda { joins("LEFT JOIN locks on 
    (posts.id = locks.post_id)").where("locks.post_id IS NULL") } 
scope :expires_within, lambda {|time| where("posts.created_at BETWEEN ? AND ?", 
    30.days.ago, time.from_now - 30.days).not_locked } 

它的工作得很好。希望能幫助其他人解決同樣的問題。

0

你應該使用子查詢,像這樣做...

scope :without_locks, :conditions => "not exists(select * from locks where posts.id = locks.post_id)" 
1

帶滑動ActiveRelation,基於字符串的LEFT JOIN s爲不可避免的;然而,使用Ruby類別Range可以大大簡化BETWEEN的計算:

scope :expires_within, lambda { |time| 
    where(:created_at => 30.days.ago..(time.from_now - 30.days)) }