2017-03-24 7 views
2

私は複数のデバイスを持つことができるステーションモデルを持っていますが、各デバイスはステーションに属しています。has_oneアソシエーションの属性でモデルをグループ化してカウントする方法は?

/app/models/station.rb

class Station < ApplicationRecord 
    has_one :address, as: :addressable, dependent: :destroy 
    has_many :devices 
end 

/app/models/device.rb

class Device < ApplicationRecord 
    belongs_to :station 
    has_one :address, through: :station 
end 

/アプリ/モデル:各ステーションがアドレスを有し、これは、多型モデルであります

:/address.rb

# @attr [String] city City name of address 
class Address < ApplicationRecord 
    belongs_to :addressable, polymorphic: true 
end 

今、私は私のチャートのデータの2つのセットを必要とします都市別の局の

  • 都市別のデバイスの
  • 数都市で局数を取得している作品は何

def stations_by_city 
    # collect data 
    tmp_result = Address.where(addressable_type: 'Station').group(:city).count 
    # sort and return top five cities 
    result = Hash[tmp_result.sort_by { |_k, v| -v }[0..4]] 
    # result = {"City-1"=>17, "City-2"=>14, "City-3"=>14, "City-4"=>12, "City-5=>11} 
end 

市のISNによってデバイスのために同じことを行います」期待どおりに働いています。これで今私はこのようにします:

私は重複したデータベース検索をしており、一般的にはかなり醜いです。どのようにしてこのクエリをより良い方法で書くことができますか?さまざまな[.joins、.where、.group]の組み合わせを試しましたが、それらの組み合わせは機能しませんでした。デバイスモデルにthrough: :stationを追加すると、他の場所で助けたが、私の問題を単純化しませんでした...デバイスモデルから参加し始め答え

# 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 

から

Updateが最速のいずれかです。

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) 

答えて

0

あなたでしjoinsAddressStation間とDeviceモデルとgroup_by RESその後、都市別ultsと適用count

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 

このクエリでは、すべての情報を取得するために、単一のデータベース検索を行います。

Deviceモデルから参加を開始することもできます。しかし、あなたは仕事に、このために、ネストされた団体に加入する必要があります。

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 

あなたはthe docs

+0

Worksでより多くの情報を確認することができます。これは接続リンクなので、私は駅でこの参加を開始する必要があります。私はどういうわけか、私が探していたデバイスやデバイスから始めました;-) –

+0

@MarkTowd 'Device'モデルから始める方法を示す答えが更新されました: – Aegis

+0

もう一度お返事ありがとうございます。 。 –

関連する問題