你会遇到麻烦,因为 Rails 期望 type 用于 Single Table Inheritance。您还需要告诉 Rails relations 上的 ID 不是 user_id,这将是 has_many 的默认值。由于您有两个关系方向,因此您需要同时声明两者。
has_many :outgoing_relations, class_name: 'Relation', foreign_key: 'initiator_id'
has_many :incoming_relations, class_name: 'Relation', foreign_key: 'initiatee_id'
从那里开始,最简单的事情就是编写一个聚合其他用户的方法:
def friends(params = {})
outgoing_relations.where(params).includes(:initiatee).map(&:initiatee) +
incoming_relations.where(params).includes(:initiator).map(&:initiator)
end
> User.first.friends(is_confirmed: true, kind: 0)
=> [#<User id: 2, created_at: "2015-08-28 15:11:12", updated_at: "2015-08-28 15:11:12">]
在直接 SQL 中,您可以轻松地通过 UNION 几个查询来提取您想要的其他用户 ID,然后用它们做您喜欢的事情。
SELECT initiatee_id AS id
FROM relations
WHERE initiator_id = 2
AND kind = 0
AND is_confirmed
UNION
SELECT initiator_id AS id
FROM relations
WHERE initiatee_id = 2
AND kind = 0
AND is_confirmed
;
id
----
1
3
这是我正在运行的数据:
SELECT * FROM users;
id | created_at | updated_at
----+----------------------------+----------------------------
1 | 2015-08-28 15:11:10.631187 | 2015-08-28 15:11:10.631187
2 | 2015-08-28 15:11:12.911575 | 2015-08-28 15:11:12.911575
3 | 2015-08-28 15:14:27.762946 | 2015-08-28 15:14:27.762946
SELECT * FROM relations;
id | initiator_id | initiatee_id | is_confirmed | kind
----+--------------+--------------+--------------+------
1 | 1 | 2 | t | 0
2 | 3 | 2 | t | 0