LoginSignup
1
0

More than 1 year has passed since last update.

groupメソッドの応用(関連先テーブルのデータをグループ化して表示する方法)

Posted at

groupメソッドとは?

指定したカラムの各値ごとにグループ化するメソッド。

下記のテーブルから、各ownerのcatの数のデータを抽出してみる。

20221002_ownersテーブルの画像(sex,incomeカラムとレコード数を追加).png

20221002_catsテーブルの画像.png

(catsテーブルからowner_idごとにグループ化し、ownerごとに何匹ネコを飼っているか数え上げる)

irb(main):045:0> Cat.group(:owner_id).count
   (0.2ms)  SELECT COUNT(*) AS count_all, "cats"."owner_id" AS cats_owner_id FROM "cats" GROUP BY "cats"."owner_id"
=> {1=>2, 2=>1, 3=>1}

この場合、owner_id=1の人(田中さん)が2匹、owner_id=2の人(伊藤さん)が1匹、owner_id=3の人(高橋さん)が1匹
ただこれだと少しわかりにくい。。。(理想は、〇〇さんが何匹飼っているみたいにわかれば良い。)

今度は、各ownerがcatを何匹飼っているのかをownerのnameごとに分けたネコの数のデータ抽出してみる。

結果は、下記の通り。

(catsテーブルとownersテーブルを内部結合したデータを抽出。つまり今回でいうと飼われているcatのみのデータが残る。)

irb(main):052:0> Cat.joins(:owner)
  Cat Load (0.3ms)  SELECT "cats".* FROM "cats" INNER JOIN "owners" ON "owners"."id" = "cats"."owner_id" /* loading for inspect */ LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Cat id: 1, name: "クロ", owner_id: 2, created_at: "2022-10-01 01:17:50.679955000 +0000", updated_at: "2022-10-01 01:17:50.679955000 +0000">, #<Cat id: 2, name: "モモ", owner_id: 1, created_at: "2022-10-01 01:18:33.127365000 +0000", updated_at: "2022-10-01 01:18:33.127365000 +0000">, #<Cat id: 3, name: "ハナ", owner_id: 3, created_at: "2022-10-01 03:10:26.125535000 +0000", updated_at: "2022-10-01 03:10:26.125535000 +0000">, #<Cat id: 4, name: "ミー", owner_id: 1, created_at: "2022-10-01 01:19:31.494863000 +0000", updated_at: "2022-10-01 01:19:31.494863000 +0000">]>


今回は、catsテーブルのcatは全て飼われているので、catsテーブルは上記の内容のままである。

(次に、内部結合したcatsテーブルをownersのnameごとにグループ化し、そのcatの数を出力しようとし、下記コマンドを実行。)

irb(main):053:0> Cat.joins(:owner).group("owner.name").count
   (0.7ms)  SELECT COUNT(*) AS count_all, "owner"."name" AS owner_name FROM "cats" INNER JOIN "owners" ON "owners"."id" = "cats"."owner_id" GROUP BY "owner"."name"
Traceback (most recent call last):
        1: from (irb):53
ActiveRecord::StatementInvalid (SQLite3::SQLException: no such column: owner.name)


ただし、エラー発生。ActiveRecord::StatementInvalid (SQLite3::SQLException: no such column: owner.name)の内容は、「ActiveRecord::StatementInvalid (SQLite3::SQLException: そのような列はありません: owner.name)」。
つまり、ownerにはnameカラムがないということ。groupメソッド内の引数owner.nameのownerをownersに変更し、そのnameカラムの値ごとにグループ化する。
(*今回の状況で使用したgroupメソッドの引数には、owners.nameのようにテーブル名.カラム名でなければ、グループ化できないらしい。)

(ownersテーブルのnameの値ごとにグループ化し、それぞれのcatの数を数える。)

irb(main):054:0> Cat.joins(:owner).group("owners.name").count
   (0.3ms)  SELECT COUNT(*) AS count_all, "owners"."name" AS owners_name FROM "cats" INNER JOIN "owners" ON "owners"."id" = "cats"."owner_id" GROUP BY "owners"."name"
=> {"伊藤"=>1, "田中"=>2, "高橋"=>1}


上記内容より、伊藤さんは1匹、田中さんは2匹、高橋さんは1匹といったデータを得ることができた。

1
0
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
1
0