2013-10-12 67 views
0

我想通過標記進行搜索,所以我需要一個exists查詢,但我仍然需要在所有標記上加入連接。我嘗試了幾種方法,並且我沒有想法。Rails ActiveRecord在指定範圍內通過標記查找問題

的Qustion - 標籤關係是通過has_and_belongs_to_many兩種方式(即我有一個QuestionTags木匠表)

例如

Question.join(:tags).where('tag.name = ?', tag_name).includes(:tags)

我希望它可以做什麼,我需要的,但實際上它只是搗爛了includesjoin和我剛剛結束了與基本內連接。

Question.includes(:tags) 
    .where("exists (
       select 1 from questions_tags 
       where question_id = questions.id 
        and tag_id = (select id 
            from tags 
           where tags.name = ?))", tag_name) 

此獲取正確的結果,但一)實在是太醜了,和b)給出了一個折舊的警告,又似乎混淆includesjoin

棄用警告:看起來你是在字符串SQL sn ippet中引用的熱切加載表(一個 :questions,tags)。對於 例如:

Post.includes(:comments).where("comments.title = 'foo'") 

注意我試圖寫這些的命名範圍。

讓我知道如果問題不明確。提前致謝。

+0

說實話,我很困惑,爲什麼內部聯接是不是你不夠好,你能請到更詳細爲什麼加入標籤工作不適合你? –

+0

@EdgarsJekabsons,因爲我需要顯示所有帶有特定標籤的問題列表,但在該列表中仍需要顯示每個問題的所有標籤,避免N + 1查找。例如。點擊上面的'sql'標籤來查看我需要的SO頁面。只有內部連接,頁面將只顯示每個問題下的'sql'標籤。 – fearofawhackplanet

回答

1

好的,明白了。我知道沒有內置的語法來做到這一點。我之前使用過替代方法,您可以這樣做:

Question.include(:tags).where("questions.id IN (
#{ Question.joins(:tags).where('tags.name = ?', tag_name).select('questions.id').to_sql})") 

您也可以將此子查詢加入到您的問題表中,而不是使用IN。或者,如果您不反對添加寶石,並且您正在使用Postgres,請使用gem。 它爲高級查詢提供了非常整潔的語法。

+0

謝謝,這個工程,但我再次得到棄用警告,有沒有辦法解決這個問題? – fearofawhackplanet

+0

你嘗試過'where'方法後面添加includes嗎? –

+0

是的,它沒有區別。即使是與不相關的包含內容,我也會收到此警告。 'Question.tagged( 「SQL」)包括(:投票)'。在我看來,一個錯誤的軌道,我有同樣的問題,同時具有'加入'和'includes'的任何查詢。 – fearofawhackplanet

0

使用preload而不是includes

Question.preload(:tags).where("exists ....