新问题:
更简单的测试用例,创建数据库
CREATE USER test WITH PASSWORD $$test$$;
CREATE DATABASE test;
GRANT ALL PRIVILEGES ON DATABASE test TO test;
# add to pg_hba.conf if needed
数据映射器设置:
require 'data_mapper'
DataMapper::Logger.new($stdout, :debug)
DataMapper.setup(:default, 'postgres://test:test@127.0.0.1/test')
class Membership
include DataMapper::Resource
property :id, Serial
property :ended_at, DateTime
belongs_to :user, key: true
belongs_to :group, key: true
end
class Group
include DataMapper::Resource
property :id, Serial
property :name, String
has n, :memberships
has n, :users, through: :memberships
end
class User
include DataMapper::Resource
property :id, Serial
property :name, String
has n, :memberships
has n, :groups, through: :memberships
end
DataMapper.finalize
DataMapper.auto_migrate!
u1 = User.create name: 'u1'
u2 = User.create name: 'u2'
g1 = Group.create name: 'g1'
g2 = Group.create name: 'g2'
g3 = Group.create name: 'g3'
u1.groups << g1
u1.groups << g3
u2.groups << g2
g3.users << u2
u1.save
u2.save
g3.save
# User.all = [#<User @id=1 @name="u1">, #<User @id=2 @name="u2">
# Group.all = [#<Group @id=1 @name="g1">, #<Group @id=2 @name="g2">, #<Group @id=3 @name="g3">]
# Membership.all = [#<Membership @id=1 @ended_at=nil @user_id=2 @group_id=2>, #<Membership @id=2 @ended_at=nil @user_id=2 @group_id=3>, #<Membership @id=3 @ended_at=nil @user_id=1 @group_id=1>, #<Membership @id=4 @ended_at=nil @user_id=1 @group_id=3>]
如何从所有某个组中获取用户的所有 id,以及从某些用户的组中获取所有 id?
user_ids = [1,2]
User.all(id:user_ids).what???
# desired output: {'1' => [1,3], '2' => [2,3]}
# user with ID=1, has two groups (with ID=1 and ID=3)
# user with ID=2, also has two groups (with ID=2 and ID=3)
group_ids = [1,3]
Group.all(id:group_ids).what???
# desired output: {'1' => [1], '3' => [2,3]}
# group with ID=1, has one user (with ID=1)
# group with ID=3, has two users (with ID=2 and ID=3)
老问题:
例如,如果我有 3 张桌子
class Human
include DataMapper::Resource
property :id, Serial
property :name, String
has n, :memberships
end
class Group
include DataMapper::Resource
property :id, Serial
property :name, String
has n, :memberships
end
class Membership
include DataMapper::Resource
property :ended_at, DateTime
belongs_to :human, key: true
belongs_to :group, key: true
end
如何从人类那里获取所有 Group.id?或组中的 Human.id?所以它会像这样显示:
human_ids = [1,3,4]
group_ids = Human.get_all_group_ids??? human_ids
group_ids # { '1' => [3,5,7], '3' => [1,9], '4' => [6,7,9,12] }
是否可以在 DataMapper 上以简单的方式做到这一点?尽可能以最有效的查询?
还是我应该手动做?
sql = "
SELECT x1.id AS hid, x3.id AS gid
FROM humans x1
LEFT JOIN memberships x2
ON x1.id = x2.human_id
LEFT JOIN groups x3
ON x2.group_id = x3.id
WHERE x1.id IN ( #{human_ids.join ','} )
ORDER BY 1,2
"
rows = repository(:default).adapter.select sql
res = {}
rows.each do |row|
hid = row[:hid]
res[hid] = [] if res[hid].nil?
res[hid] << row[:gid]
end
# res is the result