2011-07-20 25 views
1

在我的Rails型號我有:在Rails 3中,如何選擇items.join_model.id!= x的項目?

class Song < ActiveRecord::Base 
    has_many :flags 
    has_many :accounts, :through => :flags 
end 

class Account < ActiveRecord::Base 
    has_many :flags 
    has_many :songs, :through => :flags 
end 

class Flag < ActiveRecord::Base 
    belongs_to :song 
    belongs_to :account 
end 

我正在尋找一種方式來創建於宋模型,取不具有與其相關聯的定帳戶的歌曲範圍。

我已經試過:

Song.joins(:accounts).where('account_id != ?', @an_account) 

但它返回一個空集。這可能是因爲有歌曲沒有帳戶附加到它?我不確定,但真的很苦惱這個。

更新

的結果集我正在尋找包括沒有與之相關的定帳戶的歌曲。這包括沒有標誌的歌曲。

感謝您的期待。

+0

您可以發佈** Song.joins的SQL輸出(:帳戶)( '?ACCOUNT_ID ==',@an_account)。凡** – Gazler

+0

我貼錯了代碼到我的問題。它應該是!=。但是,這裏是SQL輸出:'SELECT「歌曲。* FROM」歌曲「INNER JOIN」flags「ON」歌曲「。」id「=」flags「。」song_id「INNER JOIN」accounts「ON」accounts「。 「id」=「flags」。「account_id」WHERE(account_id!= 1)ORDER BY類型ASC,標題ASC' – jklina

+0

你可以嘗試用includes(:accounts)替換連接(:accounts)嗎? – Gazler

回答

2

我是否正確理解你的問題 - 你想要的歌曲與特定帳戶沒有關聯?

嘗試:

Song.joins(:accounts).where(Account.arel_table[:id].not_eq(@an_account.id)) 

答修訂:(響應澄清評論)

您可能希望SQL條件是這樣的:

Song.all(:conditions => 
    ["songs.id NOT IN (SELECT f.song_id FROM flags f WHERE f.account_id = ?)", @an_account.id] 
) 

或者在阿雷爾,你可以得到像這樣生成的相同的SQL:

songs = Song.arel_table 
flags = Flag.arel_table 

Song.where(songs[:id].not_in(
    flags.project(:song_id).where(flags[:account_id].eq(@an_account.id)) 
)) 

我通常更喜歡ARel,在這種情況下我也更喜歡它。

+0

謝謝Scott,這是正確的。當帳戶標記歌曲時,我不希望爲標記該歌曲的帳戶選擇該歌曲。我運行了你的查詢並收到了和我一樣的空集。這裏是SQL輸出:'SELECT'songs「。* FROM」songs「INNER JOIN」flags「ON」songs「。」id「=」flags「。」song_id「INNER JOIN」accounts「ON」accounts「。」id 「=」flags「。」account_id「where(」accounts「。」id「!= 1)ORDER BY genre ASC,title ASC' – jklina

+0

@jklina - SQL看起來正確。數據庫中的原始數據關聯是否正確?我的意思是,如果沒有與該特定帳戶關聯的標誌,則空的結果集可能被認爲是正確的。這可能聽起來像一個愚蠢的問題,但這些事情確實發生。如果數據庫處於正確的狀態,查詢看起來會對我有用。檢查你的數據在DB – Scott

+0

中的外鍵關係我對這種混淆表示歉意,但這就是我正在尋找的結果集 - 沒有給定帳戶的結果集,無論它是否有其他帳戶或沒有帳戶。 – jklina

0

如果您的where子句不是拼寫錯誤,那麼這是不正確的。代碼經常使用==平等,但SQL不,使用單個等號這樣:

Song.joins(:accounts).where('account_id = ?', @an_account.id) 

編輯:

居然還有就是使用ActiveRecord來爲你做這個的一種方式,而不是編寫自己的綁定SQL片段:

Song.joins(:accounts).where(:accounts => {:id => @an_account.id}) 
+0

對不起,我粘貼了錯誤的代碼。我正在測試它是否適用於==。它應該是!=。我更新了我的問題。 – jklina