私は複数のデバイスを持つことができるステーションモデルを持っていますが、各デバイスはステーションに属しています。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)
Worksでより多くの情報を確認することができます。これは接続リンクなので、私は駅でこの参加を開始する必要があります。私はどういうわけか、私が探していたデバイスやデバイスから始めました;-) –
@MarkTowd 'Device'モデルから始める方法を示す答えが更新されました: – Aegis
もう一度お返事ありがとうございます。 。 –