2012-02-05 53 views
0

例如,我有2個表格:主題和註釋。加入表格 - Rails 3中的關聯

主題has_many評論。評論屬於主題。

評論表有專欄sender_id我保存用戶的ID,誰創建此評論。

任務:選擇未由該用戶評論的主題的id(我知道user_id)。 (我想用一個查詢來完成)。

早些時候我這樣做。 (兩個查詢)(我的數據庫 - PostgreSQL的)

incorrect_topics = Comment.select(:topic_id).where(:sender_id => user_id).map { |elem| elem.topic_id } 
ids = select(:id).where(["id NOT IN (?)", incorrect_topics]).map { |elem| elem.id } 

它工作正常,但我想,如果應用程序變大這將是嚴重的問題。

謝謝。

回答

1

如果你需要的是ID的,那麼你可以繞過所有ActiveRecord的東西,用手做:

ids = connection.select_rows(%Q{ 
    select id 
    from topics 
    where id not in (
     select topic_id 
     from comments 
     where sender_id = #{user_id.to_i} 
    ) 
}).map { |r| r.first.to_i } 

如果你是一定的user_id已經是整數,那麼你不需要.to_i。您也可以使用#{connection.quote(user_id)}。如果您想避免用map手動解開行,您也可以使用與select_values相同的SQL。

如果你想要的主題實例然後find_by_sql將是一種選擇:

topics = find_by_sql(%q{ 
    select * 
    from topics 
    where id not in (
     select topic_id 
     from comments 
     where sender_id = :user_id 
    ) 
}, :user_id => user_id) 

有些東西更清晰,當你直接使用SQL比當您嘗試包起來的東西的ActiveRecord。

+0

我沒有嘗試,但它必須工作。但是,我可以做不通過查詢中的查詢。但只有一個查詢?不能加入幫助我嗎? JOIN可以更快嗎? – makrusak 2012-02-05 09:24:29

+1

@ rusak1:查詢優化器將知道如何處理這樣的簡單查詢,並且它具有清晰的優勢。 – 2012-02-05 09:39:51

+0

最後一個問題:您對JOIN有什麼看法?它快嗎?數據庫很難嗎? – makrusak 2012-02-05 09:45:04

0

也許這樣的事情可以工作:

incorrect_topics = Comment.where('sender_id <> ?', user_id).topics 

讓我知道如果反正可以幫助你。

+1

考慮用戶1和用戶2對主題3,Comment.where('sender_id <>?',user_id)進行了評論,即使用戶2對其進行了評論,.topics也會爲您提供主題3。 – 2012-02-05 09:02:26

+0

Kleber S.,謝謝你的變體,但它是不正確的。畝太短是正確的。 – makrusak 2012-02-05 09:13:28