【问题标题】:How to get build Rails ActiveRecord query to group objects that belong_to other model?如何构建 Rails ActiveRecord 查询以对属于其他模型的对象进行分组?
【发布时间】:2017-05-21 14:09:00
【问题描述】:

给定以下模型:

ServiceCenter
  has_many :country_codes

CountryCode
  belongs_to :service_center

什么是 ActiveRecord 查询,它将返回如下内容:

{
  "US": ["United States"],
  "PT": ["Portugal", "Spain", "Estonia"],
  "FR": ["France", "Germany", "Austria"]
}

其中键是每个 ServiceCenter 的 country 属性,值是属于它的每个 CountryCode 的 country_name 属性? 换句话说,我只想要一个列表CountryCodes 属于每个 ServiceCenter,只显示那些属性。

{ 'service_centers.country': 'country_code.country_name', 'country_code.country_name' }

我试过这个:

CountryCode .joins(:service_center) .select('country_codes.country_name', 'service_centers.country') .group('service_centers.country')

但这会返回:

<ActiveRecord::Relation [
  <CountryCode id: nil, country_name: "Portugal">,
  <CountryCode id: nil, country_name: "United States">,
  <CountryCode id: nil, country_name: "Portugal">.....]>

我也尝试了ServiceCenter.joins(:country_code)....,但结果相似——ActiveRecord 与 ID 为 nil 的 ServiceCenter 对象的关系,并给出了 country 属性。

我看过与此类似的答案:Get all records grouped by field from association and sorted by count in group,但我不想数。

如果有任何帮助,我将不胜感激!

【问题讨论】:

  • 在mysql数据库中很难完全实现,它没有array/hstore数据类型(像postgresql一样),所以你不能对hash-like数据结构进行转换。
  • 啊,也许这就是我所缺少的。我有一种感觉,我知道这是可能的,而且我以前见过类似的东西,但可能是使用 Postgresql。

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


【解决方案1】:

不建议获取以下所有记录,因为它会有优化问题。但是,为了您的理解,您可以尝试:

hash = {}

ServiceCenter.all.each do |service_center|
  hash[service_center.country] = service_center.country_codes.pluck(:country_name)
end

hash 的输出类似于,例如:

{
  "US": ["United States"],
  "PT": ["Portugal", "Spain", "Estonia"],
  "FR": ["France", "Germany", "Austria"]
}

注意:哈希不能有你指定的多个值,它应该是数组的形式。

编辑

不完全是您想要的,但这可能会有所帮助:

ServiceCenter.joins(:country_codes).group("service_center_id").pluck("service_centers.country, GROUP_CONCAT(country_codes.country_name)")

输出

[["US", "United States"], ["PT", "Portugal, Spain, Estonia"], ["FR", "France, Germany, Austria"]]

【讨论】:

  • 谢谢@Abhi。是的,我考虑过只用 Ruby 来做,但我特别想知道是否有办法用 ActiveRecord 来做。您提到了一个优化问题-您是在考虑内存还是时间? Ruby 与 Arel 的优化优势是什么?
  • 哦,别管优化问题了——我之前看错了。我明白你的意思了。在ServiceCenter.all.includes(:country_codes) 上调用.each 会提高性能。
  • 可以,谢谢!我不知道 GROUP_CONCAT - 在这种情况下非常有用。
猜你喜欢
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
  • 2014-06-01
  • 2013-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多