LoginSignup
14
13

More than 5 years have passed since last update.

ActiveRecordのモデルで集計テーブルの結果を扱う

Posted at

ActiveRecordのモデルで集計テーブルの結果を扱う

通常のテーブルのモデルから、別のテーブルでの集計した結果をひもづけて取得したかったので、集計テーブルとモデルでJoinして、取得できるようにした。

集計テーブル取得用処理の作成

まず、集計テーブル取得用処理をUserのモデルに実装します。

集計部分は、ActiveRecord的に書く必要も特になかったので、SQL直で記述しています。joinした後の結果の取得時に対象の指定が必要なので、そこはselectで対象の集計テーブルの名前を指定しておく。

    def add_item_stats
      item_stats = <<-SQL
      (select
        user_id,
        count(case when is_public = 1 then 1 end) as public_item_count,
        count(1) as all_item_count
      from
        items
      group by user_id)
      SQL
      joins("left outer join #{item_stats} stats on users.id = stats.user_id").select('stats.*')
    end

ActiveRecordのモデルからの利用方法

使用する際は、Userのモデルの取得先を指定した上で、使用します。

例えば、idが1のユーザーに対して、集計テーブルとjoinした結果を取得したい場合は、下記のように書きます。

user = User.select('users.*').where(id: 1).add_item_stats.first

実行されるSQLは下記のようになります。

> user = User.select('users.*').where(id: 1).add_item_stats.first
  User Load (0.5ms)  SELECT  users.*, stats.* FROM `users` left outer join       (select
        user_id,
        count(case when is_public = 1 then 1 end) as public_item_count,
        count(1) as all_item_count
      from
        items
      group by user_id)
 stats on users.id = stats.user_id WHERE `users`.`id` = 1  ORDER BY `users`.`id` ASC LIMIT 1

取得した結果をモデルから結果を取得する場合は、通常のカラム同様、user.all_item_countといった形でアクセスできるようになります。

14
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
13