2009-09-07 45 views
0

我正在嘗試創建一個像User.not_in_project(project)這樣的命名範圍,但我無法找到正確的方法。複雜的named_scope:查找不屬於某個項目的用戶

我有用戶,項目和義務爲連接模式:

class User < ActiveRecord::Base 
    has_many :duties, :extend => FindByAssociatedExtension 
    has_many :projects, :through => :duties 
end 

class Duty < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :project 
end 

class Project < ActiveRecord::Base 
    has_many :duties 
    has_many :users, :through => :duties 
end 

我試着用named_scope類似這樣的發現條款:

User.all(:joins => :duties, :conditions => ['duties.project_id != ?', my_project]) 

但不返回用戶我誰沒有my_project,但擁有除my_project以外的項目的用戶。

換句話說,我想命名的範圍,表現得完全像這樣的方法:

def self.not_present_in p 
    self.all.reject{|u| u.projects.include?(p)} 
end 

我怎麼能這樣做?

+0

你想回來什麼?我不清楚這一點。 – 2009-09-07 11:48:17

+0

我想要一個與此方法完全相同的命名範圍: def self.not_present_in p self.all.reject {| u | u.projects.include?(p)} end 我希望它返回沒有將Project作爲參數傳遞的用戶。 請幫忙嗎? – 2009-09-07 15:39:57

+0

我編輯了這個問題以包含上面的說明,因爲它包含源代碼。 – 2009-09-07 15:43:04

回答

1

在SQL思想,查詢應該是這樣的:

select id 
    from users 
where id not in (select id 
        from users join duties on users.id = duties.user_id 
        join projects on duties.project_id = projects.id 
        where projects.id = %) 

但我也不太清楚它是如何工作的使用named_scope。我會說使用類似

def self.not_present_in p 
    find_by_sql ["select id from users where id not in (select id from users join duties on users.id = duties.user_id join projects on duties.project_id = projects.id where projects.id = ?)", p] 
end 

不像使用AR,但會工作(並保存一些查詢,可能)漂亮。

+0

謝謝Yaraher,你提供的sql查詢工作,因爲我想要一個小的修復。在第二次選擇之後,我不得不用「users.id」替換「id」以避免模棱兩可。 不過,我不能在named_scope :(使用的find_by_sql。 – 2009-09-08 07:33:54

+0

但是,爲什麼你需要的是一個名爲範圍是什麼?對於其他方法合併呢? 除非是那樣的話,它應該工作的罰款。 而如果你確實想在稍後改進它,你總是可以提交一個類似於AR使用的選項哈希,並將它與find_by_sql查詢連接/合併。可能有點額外的工作,但它可能會和你一樣可以得到。ORMs不總是讓我們不使用SQL :) – Yaraher 2009-09-08 12:24:57