我整天都被困在这一天。我有一个类似下面的设置。我正在尝试使用group_memberships关联定义朋友。
class User < ActiveRecord::Base
has_many :group_memberships
has_many :groups, :through => :group_memberships
has_many :friends # what goes here? <<
end
class GroupMembership < ActiveRecord::Base
belongs_to :user
belongs_to :role
belongs_to :group
end
class Role < ActiveRecord::Base
has_many :group_memberships
end
class Group < ActiveRecord::Base
has_many :group_memberships
has_many :users, :through > :group_memberships
end
我想在没有为朋友创建联接表的情况下这样做,除非没有这样做是完全疯狂的。
group_membership表包含user_id和group_id,将一个用户链接到一个组。
我想要
@user.friends
使用group_id返回具有公共group_membership的用户。
has_many :friends, :through => :group_memberships, :source => :group
我没有尝试过任何工作,但我会说明我完全误解了上述代码。
答案 0 :(得分:4)
不幸的是,Rails不允许你将has_many的嵌套深度超过2个..忘记将它命名为friends
一会儿(让我们称之为users
),理论上这就是你的想法想:
has_many :group_memberships
has_many :groups, :through => :group_memberships
has_many :users, :through => groups
除非这不起作用。如果你尝试它,你会看到this不那么有用的错误消息来自this位代码,特别是source_reflection.options[:through].nil?
。也就是说,through
本身不允许through
。
相反,你可能想要做这样的事情:
class User < ActiveRecord::Base
has_many :group_memberships
has_many :groups, :through => :group_memberships
def friends
groups.with_users.map(&:users).flatten.uniq.reject{|u| u == self}
end
end
class Group < ActiveRecord::Base
has_many :group_memberships
has_many :users, :through => :group_memberships
named_scope :with_users, :include => :users
end
使用Radar提到的nested_has_many_through
插件。看起来github上的至少one fork已更新为最新的Rails。
或者,只是为了踢,你可以用一个大的SQL查询来做到这一点:
class User < ActiveRecord::Base
has_many :group_memberships
has_many :groups, :through => :group_memberships
def friends
sql = <<-SQL
SELECT users.* FROM users, (
SELECT DISTINCT gm2.user_id AS user_id
FROM group_memberships gm, groups g, group_memberships gm2
WHERE gm.user_id = ? AND g.id = gm.group_id AND gm2.group_id = g.id AND gm2.user_id != ?
) AS user_ids
WHERE users.id = user_ids.user_id
SQL
User.find_by_sql([sql, id, id])
end
end
答案 1 :(得分:1)
答案 2 :(得分:0)
委托:users,:to =&gt; '基团'