Ruby DataMapper的多对多获取所有外来ID

Ruby DataMapper的多对多获取所有外来ID,ruby,ruby-datamapper,Ruby,Ruby Datamapper,新问题: 更简单的测试用例,创建一个数据库 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.set

新问题:

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

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>] 
老问题:

例如,如果我有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

也许是这样,从人类获取所有组ID

Group.all(id: memberships(&:group_ids).flatten)
从组中获取所有人类ID

Human.all(id: memberships(&:human_ids).flatten)

我不知道为什么,但它显示:NoMethodError:main:object的未定义方法“memberships”关系是成员身份还是成员身份?也许你应该两种都试试。
Human.all(id: memberships(&:human_ids).flatten)