0

のような名前付きスコープを作成しようとして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

named_scopeこのfind句に似たものを試しました:

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

どうやってやるの?

4

1 に答える 1

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 を使用するほどきれいではありませんが、機能します (そして、おそらくいくつかのクエリを節約できます)。

于 2009-09-07T19:19:25.407 に答える