ActiveRecord选择列,其中一列是关系中单个属性的数组

时间:2018-04-13 03:18:07

标签: postgresql ruby-on-rails-4 activerecord

class Building < ActiveRecord::Base
  # id
  # name
  # url

  has_many :floors
end

class Floor < ActiveRecord::Base
  # id
  # building_id
  # name
  # number

  belongs_to :building
end

我想在Building模型中添加一个返回以下内容的方法:

def self.some_stuff
  [{
    id: "81b0bd96-20e9-4f01-9801-59f3d9b99735",
    url: "http://www.google.com",
    numbers: [4,5,6,7,8,9]
  },
  {
    id: "5de096dd-f282-41cc-8300-b972fb61ea41",
    url: "http://www.yahoo.com",
    numbers: [2,7,11]
  }]
end

理想情况下,我想将其设为可链接,以便我可以执行以下操作:

Building.all.limit(100).some_stuff

编辑1:

以下是我想要在postgresql中看到的内容:

SELECT
    B.id,
    B.url,
    array_agg(F.floor_number) AS numbers
FROM
    buildings AS B
    LEFT OUTER JOIN floors AS F ON
        F.building_id = B.id
GROUP BY
    B.uuid;

编辑2:

以下内容为我提供了我想要的数据,但格式非常糟糕(因为采摘)。如果我改变采摘选择它休息。

def self.some_stuff
  fields = "buildings.id, buildings.url"
  joins(:floors)
    .includes(:floors)
    .group(fields)
    .pluck("#{fields}, array_agg(floors.floor_number)")
end

2 个答案:

答案 0 :(得分:0)

您可能希望some_stuff方法看起来像这样:

class Building
  def self.some_stuff
    map do |building|
      {
        id: building.id,
        url: building.url,
        numbers: building.floors.pluck(:number)
      }
    end
  end
end

答案 1 :(得分:0)

def self.some_stuff
  includes(:floors).map do |b|
    {
      id: b.id,
      url: b.url,
      numbers: b.floors.map(&:number)
    }
  end
end

Josh的回答略有修改。添加了includes并将pluck更改为map以避免n + 1个查询。