2010-12-14 22 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エラーが発生するからです。

そして、あなたの質問に答えるために:あなたは、私がsession_type_idている「私を得るのセッションのようにフィルタリングするSQLを変更することができる方法

知っている 『43』を、彼らは 『44』を持つことはできません

sessions_without_type_44から結果を取り出し、それを使用する第43でSESSIONTYPEを選択し、組合を通じてそのSESSIONTYPEに属し、そのIDがsessions_without_type_44内にあるすべてのセッションを取得:。

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

はい、私はいくつかのシンタックスの変更でうまく動作します。 session_types_44 =セッション。(:all、:conditions => {: "session_types.id" => 44})。 ) "、session_types_44.collect {| s | s.id}]) –

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ビットに統合する方法を見つける必要があります。 –

+0

'find_by_sql'はどうですか? Rails 3を使用している場合は、ARELでこれを行う簡単な方法があります。 – Matt

+0

私はそれを可能にする必要があります。ちょうどあなたが助けることができる間に、私はどのように私は "session_type_id '43'を持ってセッションを取得するようにフィルタにSQLを変更することができます知っているが、 '44'"を持ってはいけません。ありがとう。 –

0

これを試してみてください:

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

includeオプションはLEFTは、したがって、このクエリは動作しますJOINを使用しています。

関連する問題