11

でレコードを見つけ、私は2つのモデルがあります:RailsのHABTMと関連がない

class User < ActiveRecord::Base 
    has_and_belongs_to_many :groups 
end 

class Group < ActiveRecord::Base 
    has_and_belongs_to_many :users 
end 

私はスコープ(それは重要です - 効率化のため、チェーンスコープへの能力を)したい」doesnのユーザーを返します。 tはに属します。ANYグループ。 多くの試行のあと、スコープの代わりにメソッドを実行するのに失敗しました。collectUser.allにすると、醜いです。

助けが必要ですか?

多分2番目の質問のために: 私は、与えられたグループに属しているユーザーを返すスコープを作ることができました(IDの配列として与えられます)。

scope :in_groups, lambda { |g| 
     { 
      :joins  => :groups, 
      :conditions => {:groups => {:id => g}}, 
      :select  => "DISTINCT `users`.*" # kill duplicates 
     } 
     } 

もっと良いことができますか? (Rails 3.0.9の使用)

答えて

17

暗黙的な結合テーブルの名前は、命名規則に基づいてgroups_usersとなりました。一度あなたのデータベースでそれを確認してください。古いRailsのバージョンの

scope :not_in_any_group -> { 
    joins("LEFT JOIN groups_users ON users.id = groups_users.user_id") 
    .where("groups_users.user_id IS NULL") 
} 

:新しいRailsのバージョンでは

を:それをされると仮定すると、

scope :not_in_any_group, { 
    :joins  => "LEFT JOIN groups_users ON users.id = groups_users.user_id", 
    :conditions => "groups_users.user_id IS NULL", 
    :select  => "DISTINCT users.*" 
} 
+0

ありがとう、それはトリックをしました:) – schiza

+1

あなたはDISTINが必要でしょうか?この場合、返された結果の結合関係が存在しないため、ユーザーの繰り返しはありません。 –

+0

'DISTINCT'は必要ありません。私はRails 4以上に必要な新しい構文を追加しました(私は思っています)。 – slhck

2

あなたが(もっと柔軟)会合を介しHAS_MANYするHABTMから変換する場合は、あなたが使用することができます

class Group < ActiveRecord::Base 
    has_many :groups_users, dependent: :destroy 
    has_many :users, through: :groups_users, uniq: true 

    scope :in_groups, -> { includes(:groups_users).where(groups_users: {group_id: nil}) } 
end 

class User < ActiveRecord::Base 
    has_many :groups_users, dependent: :destroy 
    has_many :groups, through: :groups_users 
end 

class GroupsUser < ActiveRecord::Base 
    belongs_to :group 
    belongs_to :user 
end 
関連する問題