has_many:through:uniq关系需要从直通表中收集所有内容

时间:2011-11-03 18:17:19

标签: sql ruby-on-rails-3 activerecord

这是一个有点难以解释的问题。所以这是一个例子。假设我在模型中有这个:

has_many :things,
  :through => :relationships,
  :source  => :thing

我需要获取things的列表以及relationships表上的任何数据。让我们说它是'relationships.name'。我们可以这样做:

has_many :things,
  :through => :relationships,
  :source  => :thing,
  :select  => 'things.*, relationships.name as rel_name'

因此,如果存在2个关系,我将获得2个对象:

 #<Thing id: 1, rel_name: "foo">
 #<Thing id: 1, rel_name: "bar">

如果我们填充:unique => true或调整选择以使用DISTINCT,我们将获得唯一的对象,但有关其中一个关系的数据将会消失。我真正想要的是唯一的things,其中所有不同的关系名称都被收集到一个访问者中:

 #<Thing id: 1, rel_names: ["foo", "bar"] >

是否有一些黑暗的SQL魔法,我不知道可以做到这一点?保留范围对我来说很重要,因此我不能循环遍历结果集来收集数据。

由于

2 个答案:

答案 0 :(得分:1)

MySQL有这种方法的GROUP_CONCAT()方法:

 has_many :things,
   :through => :relationships,
   :source  => :thing,
   :select  => 'things.*, GROUP_CONCAT(relationships.name as rel_name)'

答案 1 :(得分:1)

在MySQL上使用GROUP_CONCAT:

class MyModel < ActiveRecord::Base
  attr_accessor :rel_names

  has_many :things,
    :through => :relationships,
    :source  => :thing,
    :select  => 'things.*, GROUP_CONCAT(DISTINCT relationships.name SEPARATOR ";;") as rel_names'


  # .. your code ..

  def rel_names
    @rel_names.present? ? @rel_names.split(';;') : []
  end
end