2010-12-14 62 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,因此该查询工作。

相关问题