class Group < ActiveRecord::Base
has_many :assigns
has_many :members, :through => :assigns
end
class Member < ActiveRecord::Base
has_many :assigns
has_many :groups, :through => :assigns
end
class Assign < ActiveRecord::Base
belongs_to :group
belongs_to :member
end
if __FILE__ == $0
[Group, Member, Assign].each(&:delete_all)
(1..5).each do |i|
Group.create(:name => "group#{i}")
Member.create(:name => "member#{i}")
end
(1..5).each do |i|
(1..5).each do |j|
Assign.create(:group_id => i, :member_id => j,
:leader => rand(3).zero?) if rand(2).zero?
end
end
# リーダー連中の名前
p Member.find(:all, :include => :assigns).inject([]){|leaders, member|
returning(leaders){leaders << member.name if member.assigns.any?(&:leader?)}}
# 冗長版
p Member.find(:all, :include => :assigns).inject([]){|members, member|
members << [member, member.assigns]
}.select{|member, assigns|
assigns.any?(&:leader?)
}.map(&:first).map(&:name)
^^^^^^^ ktkr
# リーダーがいないグループの名前
p Group.find(:all, :include => :assigns).reject{|group|
group.assigns.any?(&:leader?)}.map(&:name)
# メンバーがいないグループの名前
p Group.find(:all, :include => {:assigns => :member}).select{|group|
group.members.empty?}.map(&:name)
# 多分上のと同じ意味で、ちょっと効率がヨサゲ版
p Group.find(:all, :include => :assigns).select{|group|
group.assigns.empty?}.map(&:name)
# メンバー→グループの割り当て表(リーダー属性つき)
p Member.find(:all, :include => {:assigns => :group}).inject({}){|members, member|
returning(members) do
members.store(member.name, member.assigns.map{|assign|
[assign.group.name, assign.leader?]})
end
}
end
確かに中間テーブルがモデルとして使えるのはいいですね。 ただ、問題は更新なんすよね。また今度。
まさしく has_many :through なサイトを見て、 昨日のに追記。:uniq とは関係ないけど。 class Group < ActiveRecord::Base has_many :assigns has_many :members, :through => :assigns has_many :leaders, :through => :assigns, :source => :leader, :conditions..