我的问题是:对于给定的用户,可以使用什么 SQL 命令来选择 已确认关联关系且属于给定类型的所有关联发起者/发起者?
ruby 如下:
class User < ActiveRecord::Base
has_many :relations
end
class Relation < ActiveRecord::Base
belongs_to :initiator, class_name: "User"
belongs_to :initiatee, class_name: "User"
end
class CreateRelations < ActiveRecord::Migration
def change
create_table :relations do |t|
t.references :initiator
t.references :initiatee
t.boolean :is_confirmed, default: false
t.integer :type
end
end
end
最佳答案
你会遇到麻烦,因为 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
关于mysql - SQL 查询通过关联模型选择用户的 friend ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32273329/