0

新问题:

更简单的测试用例,创建数据库

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
4

1 回答 1

0

也许是这样的,从 Human 获取所有组 id

Group.all(id: memberships(&:group_ids).flatten)

从 Group 中获取所有人类 ID

Human.all(id: memberships(&:human_ids).flatten)
于 2013-09-18T23:15:20.693 回答