2012-10-31 78 views
2

我試圖從用戶那裏獲取一些阻止「我」的帖子。下面硒型號:從非阻止用戶提取帖子

User 
    id 
    username 
    .... 

Post 
    id 
    user_id 
    content 
    ... 

Blockings 
    blocker_id 
    blocked_id 

我需要從沒有阻止我所有用戶獲取職位。

我取的所有帖子有:

@posts Post.all 

但是我加入了一起怎麼辦。

SELECT * FROM posts WHERE "posts.user_id isn't blocking me" 

我有一個叫current_user助手返回登錄的用戶「我」的電流。

+0

如果我正確理解你的意圖,SQL是'SELECT * FROM帖裏NOT EXISTS(SELECT 1 FROM的阻塞B,其中b.blocked_id = $ 1 = b.blocker_id posts.user_id)' - 其中'$ 1'是參數'current_user'。也許這將有助於制定查詢的ActiveRecord表達式;你當然可以測試SQL,並確保它做你想要的。 –

+0

它像一個魅力。謝謝。但是它有效嗎?目前我有幾百萬條記錄。 – sandelius

+0

找出最好的方法是'EXPLAIN ANALYZE'並參見。 –

回答

1

一種方法用SQL做到這一點是:

select * 
    from post 
    where user_id not in 
    (select blocker_id 
    from blockings 
    where blocked_id = 1); 

只需更換數字ID與變量。

SQL Fiddle

+0

啊,就是這樣!有時頭部不存在! :) 謝謝! – sandelius

+0

注意'NOT IN'中的NULL值。確保'blocker_id'是'NOT NULL'或者添加'WHERE blocker_id IS NOT NULL'。 –

+0

@Craig One可能會爭辯說,在這樣的表中,blocker_id不應該爲NULL。這應該由一個約束強制執行。 – jt234

0

在郵政類和這樣一個範圍:

scope :not_blocked_from, lambda{|user| where("blocked_id <> ?", user.id)} 

而且你可以獲取你想要如下那些帖子:

Post.not_blocked_from(me) 

會工作。

+0

blocked_id出現在Blocking模型中而不是Post模型中。 – sandelius

+0

哎呀,對不起,沒有仔細閱讀這個問題。不過,您可以將這些連接和條件添加到範圍中,讓您可以隨處使用它。 –