复杂的named_scope:查找不属于某个项目的用户

时间:2009-09-07 11:43:21

标签: ruby-on-rails named-scope has-many

我正在尝试创建像User.not_in_project(project)这样的命名范围,但我找不到正确的方法。

我将用户,项目和职责作为联接模式:

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

我尝试使用类似于此find子句的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

我该怎么做?

1 个答案:

答案 0 :(得分: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那么漂亮,但可以工作(并且可能会保存一些查询)。