Ruby on rails 如何通过一个has#u one关联对模型进行分组和计数';s属性?

Ruby on rails 如何通过一个has#u one关联对模型进行分组和计数';s属性?,ruby-on-rails,ruby,activerecord,active-record-query,Ruby On Rails,Ruby,Activerecord,Active Record Query,我有一个站点模型,它可以有多个设备,而每个设备都属于一个站点。每个站点都有一个地址,这是一个多态模型: /app/models/station.rb class Station < ApplicationRecord has_one :address, as: :addressable, dependent: :destroy has_many :devices end 按城市对设备进行同样的操作并不像预期的那样有效。现在我是这样做的: def devices_by_city

我有一个站点模型,它可以有多个设备,而每个设备都属于一个站点。每个站点都有一个地址,这是一个多态模型:

/app/models/station.rb

class Station < ApplicationRecord
  has_one :address, as: :addressable, dependent: :destroy
  has_many :devices
end
按城市对设备进行同样的操作并不像预期的那样有效。现在我是这样做的:

def devices_by_city
  stations = Station.all.includes(:address)
  tmp_result = {}
  # for each unique city
  list_of_cities.uniq.each do |city|
   number_of_devices = 0
   # check all stations
   stations.each do |station|         
     address = station.address
     # check if station is in city
     if address.city == city
       # and add to counter
       number_of_devices += station.devices.count
     end
    end
    # append to resulting hash
    tmp_result[city] = number_of_devices
  end
  result = Hash[tmp_result.sort_by { |_k, v| -v }[0..4]]
end

def list_of_cities
  cities = []
  stations = Station.all.includes(:address)
  stations.each do |station|
    address = station.address
    cities << address.city
  end
    cities
  end
end
从设备型号启动联接是最快的:

Timing for old query
  0.530000   0.050000   0.580000 (  0.668664)
Timing for query starting from station model
  0.020000   0.000000   0.020000 (  0.024881)
Timing for query starting from device model
  0.010000   0.000000   0.010000 (  0.009616)

您可以在
站点
地址
设备
模型之间加入
,并按城市对结果进行分组,然后应用
计数

def devices_by_city_updated
  temp_result = Station.joins(:address, :devices).group(:city).count
  result = Hash[tmp_result.sort_by { |_k, v| -v }[0..4]]
end
此查询将执行单个数据库查找以获取所有信息

您也可以从
设备
模型启动连接。但您必须加入嵌套关联才能使其工作:

def self.devices_by_city_another
  tmp_result = Device.joins(station: :address).group(:city).count
  result = Hash[tmp_result.sort_by { |_k, v| -v }[0..4]]
end

您可以在Works中查看更多信息。我必须开始这个连接站,因为这是连接链接。我不知怎的从地址或设备开始寻找。。。设备;-)@MarkTowd我更新了答案,以显示如何从
设备开始执行此操作
型号:)
# start join from station model
tmp_result = Station.joins(:address, :devices).group(:city).count

# start join from device model
tmp_result = Device.joins(station: :address).group(:city).count
Timing for old query
  0.530000   0.050000   0.580000 (  0.668664)
Timing for query starting from station model
  0.020000   0.000000   0.020000 (  0.024881)
Timing for query starting from device model
  0.010000   0.000000   0.010000 (  0.009616)
def devices_by_city_updated
  temp_result = Station.joins(:address, :devices).group(:city).count
  result = Hash[tmp_result.sort_by { |_k, v| -v }[0..4]]
end
def self.devices_by_city_another
  tmp_result = Device.joins(station: :address).group(:city).count
  result = Hash[tmp_result.sort_by { |_k, v| -v }[0..4]]
end