🙌
【Part2】ActiveRecordから学ぶSQL
はじめに
モデルのレコード数や、合計値を求めるActiveRecordで、どのようなSQLが実行されるのか確認し、SQLの基礎を固める
※以前作成した記事の続きです👇
モデル定義
内容
UserとArticleの2つのモデルを作成します。
User:Articleは1:多で関連付けます。
Userモデル
# user.rb
class User < ApplicationRecord
has_many :articles, dependent: :destroy
end
Articleモデル
# article.rb
class Article < ApplicationRecord
belongs_to :user
enum status: { private: 1, public: 2 }
end
テーブル設計
usersとarticlesテーブルの各カラムとレコードは以下になります👇
usersテーブル
id | name |
---|---|
5 | 夏目漱石 |
6 | 芥川龍之介 |
articlesテーブル
id | user_id | title | price | status |
---|---|---|---|---|
1 | 5 | 吾輩は猫である | 693 | 1(”private”) |
2 | 5 | 坊っちゃん | 286 | 2(”public”) |
3 | 5 | こころ | 407 | 1(”private”) |
4 | 6 | 羅生門 | 440 | 2(”public”) |
5 | 6 | 蜘蛛の糸 | 294 | 1(”private”) |
ActiveRecord
count(カラム名)
pry(main)> Article.count(:id)
=> 5
SELECT COUNT("articles"."id") FROM "articles"
SELECT COUNT("articles"."id")
:articles
テーブルのidカラムのレコード数
をカウントする
sum(カラム名)
pry(main)> Article.sum(:price)
=> 2120
SELECT SUM("articles"."price") FROM "articles"
SELECT SUM("articles"."price")
:articles
テーブルのpriceカラムの値の合計
を計算する
average(カラム名)
Article.average(:price).to_f
=> 424.0
SELECT AVG("articles"."price") FROM "articles"
SELECT AVG("articles"."price")
:articles
テーブルのpriceカラムの値の平均
を計算する
left_joins(関連名)
pry(main)> User.left_joins(:articles)
実行結果
=> [#<User:0x00007ff22a5e25a8
id: 5,
name: "夏目漱石",
email: "souseki@example.com",
created_at: Sun, 17 Sep 2023 01:35:43 UTC +00:00,
updated_at: Sun, 17 Sep 2023 01:35:43 UTC +00:00>,
#<User:0x00007ff22a5e24e0
id: 5,
name: "夏目漱石",
email: "souseki@example.com",
created_at: Sun, 17 Sep 2023 01:35:43 UTC +00:00,
updated_at: Sun, 17 Sep 2023 01:35:43 UTC +00:00>,
#<User:0x00007ff22a5e2418
id: 5,
name: "夏目漱石",
email: "souseki@example.com",
created_at: Sun, 17 Sep 2023 01:35:43 UTC +00:00,
updated_at: Sun, 17 Sep 2023 01:35:43 UTC +00:00>,
#<User:0x00007ff22a5e2350
id: 6,
name: "芥川龍之介",
email: "akutagawa@example.com",
created_at: Sun, 17 Sep 2023 01:37:38 UTC +00:00,
updated_at: Sun, 17 Sep 2023 01:37:38 UTC +00:00>,
#<User:0x00007ff22a5e2288
id: 6,
name: "芥川龍之介",
email: "akutagawa@example.com",
created_at: Sun, 17 Sep 2023 01:37:38 UTC +00:00,
updated_at: Sun, 17 Sep 2023 01:37:38 UTC +00:00>]
SELECT "users".* FROM "users" LEFT OUTER JOIN "articles" ON "articles"."user_id" = "users"."id"
LEFT OUTER JOIN "articles"
:2つのテーブル間の結合を行い、
左側はFROM
で指定したusers
テーブルのすべてのレコード、
右側はJOIN
で指定したarticles
テーブルから、マッチするレコードを選択する。
つまり、ユーザーが記事を持っていない場合でも、そのユーザーの情報は結果に含まれる。
おまけ
RIGHT JOIN
をサポートするActiveRecord はありませんでした。
以下のコードをRailsコンソールで実行するとRIGHT JOIN
できました。
User.joins("RIGHT JOIN articles ON articles.user_id = users.id")
実行結果
=> [#<User:0x00007ff228ffabc8
id: 5,
name: "夏目漱石",
email: "souseki@example.com",
created_at: Sun, 17 Sep 2023 01:35:43 UTC +00:00,
updated_at: Sun, 17 Sep 2023 01:35:43 UTC +00:00>,
#<User:0x00007ff228ffaad8
id: 5,
name: "夏目漱石",
email: "souseki@example.com",
created_at: Sun, 17 Sep 2023 01:35:43 UTC +00:00,
updated_at: Sun, 17 Sep 2023 01:35:43 UTC +00:00>,
#<User:0x00007ff228ffaa10
id: 5,
name: "夏目漱石",
email: "souseki@example.com",
created_at: Sun, 17 Sep 2023 01:35:43 UTC +00:00,
updated_at: Sun, 17 Sep 2023 01:35:43 UTC +00:00>,
#<User:0x00007ff228ffa920
id: 6,
name: "芥川龍之介",
email: "akutagawa@example.com",
created_at: Sun, 17 Sep 2023 01:37:38 UTC +00:00,
updated_at: Sun, 17 Sep 2023 01:37:38 UTC +00:00>,
#<User:0x00007ff228ffa808
id: 6,
name: "芥川龍之介",
email: "akutagawa@example.com",
created_at: Sun, 17 Sep 2023 01:37:38 UTC +00:00,
updated_at: Sun, 17 Sep 2023 01:37:38 UTC +00:00>]
SELECT "users".* FROM "users" RIGHT JOIN articles ON articles.user_id = users.id
参考記事
Discussion