2010-12-14 59 views
0

我堅持了幾個小時。這可能是一個快速解決方案,但現在我的大腦過熱了。好吧,在這裏。如何從Rails 2中不包含特定項目的多對多關係中選擇特定記錄?

我有Session和SessionType模型,它們之間具有多對多的關係,如下所示。

class Session < ActiveRecord::Base 
    ... 
    has_and_belongs_to_many :session_types 
    ... 
end 

class SessionType < ActiveRecord::Base 
    ... 
    has_and_belongs_to_many :sessions 
    ... 
end 

我想要的是得到它不包含任何特定session_type,如:會話,

Session.find(:all, :joins => [:session_types], :conditions => ["session_types.id <> 44"]) 

它不爲我工作,因爲上面的查詢仍將給我由於多對多關係的性質,在其許多關聯中具有session_types.id「44」的會話。

另外下面的mysql代碼也不起作用。

select sessions.* from sessions 
INNER JOIN `session_types_sessions` ON `session_types_sessions`.session_id = `sessions`.id 
WHERE ( session_types_sessions.session_type_id NOT IN (44)) 
GROUP BY sessions.id 

任何幫助將不勝感激。

謝謝。

回答

1

首先選擇那些類型44屆:

session_types_44 = Session.find(:all, :joins => :session_types, 
    :conditions => { :"session_types.id" => 44 }).uniq 

,並選擇會話不屬於上述:

sessions_without_type_44 = Session.find(:all, 
    :conditions => "id NOT IN (#{session_types_44.join(",")})") 

你需要小心,因爲如果session_types_44是空數組,你會得到SQL錯誤。

並回答您的第二問題:

你知道我怎麼能更改SQL過濾像「給我的會議已session_type_id‘43’,但他們不能有‘44’

sessions_without_type_44拍攝效果,並用它首先選擇會話類型43並通過協會獲得屬於該會話類型的所有會話和它們的ID是sessions_without_type_44內。

SessionType.find(43).sessions.all(:conditions => { 
    :id => sessions_without_type_44 }) 
+0

是的,它工作正常,有點語法變化,因爲我有一些關於連接的語法錯誤。 session_types_44 =會話。find:(:all,:joins =>:session_types,:conditions => {:「session_types.id」=> 44})。 )「,session_types_44.collect {| s | s.id}]) – 2010-12-14 16:45:54

1

試試這個:

SELECT sessions.* 
FROM sessions 
LEFT JOIN session_types_sessions ON session_types_sessions.session_id = sessions.id AND session_types_sessions.session_type_id = 44 
WHERE session_types_sessions.session_id IS NULL 
+0

太好了。在SQL中工作。我現在需要找到一種融入Rails的方法。 – 2010-12-14 15:55:55

+0

'find_by_sql'如何?如果你使用的是Rails 3,那麼在AREL中應該有一個簡單的方法來做到這一點。 – Matt 2010-12-14 15:56:48

+0

好的,我應該能夠。就在你可以幫忙的時候,你是否知道我可以如何改變SQL來過濾,如「讓我的會話有session_type_id'43',但他們不能有'44'」。謝謝。 – 2010-12-14 16:25:34

0

試試這個:

Session.all(
    :include => :session_types, 
    :conditions => ["session_types.id IS NOT NULL AND session_types.id != ?", 44]) 
) 

include選項使用LEFT JOIN,因此該查詢工作。

相關問題