ActiveRecordと呼ばれるものでSQLを発行しています。
「RubyとSQLの翻訳機」みたいなもの
Railsでモデルを定義するだけで簡単にSQLを発行することができる
※モデル:データベースにアクセスする為に準備するためのクラス
ActiveRecord色々
作成
User.create(name: "小田", email: "oda@gmail.co.jp")
INSERT INTO
`users` (`name`, `email`, `created_at`, `updated_at`)
VALUES
(
'小田',
'oda@example.org',
'2021-07-30 09:18:57',
'2021-07-30 09:18:57'
)
検索
User.all
SELECT `users`.* FROM `users`
User.first
SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1
User.find(1)
SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
User.where(title: '小田')
SELECT `users`.* FROM `users` WHERE `users`.`title` = '小田' LIMIT 1
めちゃくちゃ便利
内部結合
■joins
User.joins(:user_work_experiences).where(user_work_experience: { id: 1 })
SELECT
`users`.*
FROM
`users`
INNER JOIN `user_work_experiences` ON `user_work_experiences`.`user_id` = `users`.`id`
WHERE
`user_work_experience`.`id` = 1
外部結合
■eager_load
User.eager_load(:user_work_experiences)
SELECT
`users`.*,
`user_work_experiences`.*,
FROM
`users`
LEFT OUTER JOIN `user_work_experiences` ON `user_work_experiences`.`user_id` = `users`.`id`
eager_loadは結合先のテーブルの情報も取得できるが、joinsはできない
joinsだとuser_work_experiences.job_idは取得できない。
NG
User.joins(:user_work_experiences).where(user_work_experience: { id: 1 }).job_id
OK
User.eager_load(:user_work_experiences).where(user_work_experience: { id: 1 }).job_id
その他
preload
User.preload(:user_work_experiences)
SELECT `users`.* FROM `users`;
SELECT
`user_work_experiences`.*
FROM
`user_work_experiences`
WHERE
`user_work_experiences`.`user_id` IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
eager_loadとpreload使い分け
データ量が膨大な場合だと、preload、eager_loadは、いずれにせよ多くのメモリを必要とする。
なので、アソシエーションの種類によって使い分けるべき。
1対1あるいは1対Nのアソシエーションの場合はeager_load
データ量が増えても、1回のSQLでまとめて取得した方が効率的な場合が多いと思うので、eager_loadを良き。
N対Nのアソシエーションの場合はpreload
eager_loadよりも、preloadの方がSQLを分割して取得するため、レスポンスタイムは早くなるので、preloadが良き。
デメリット
ActiveRecordに頼りすぎるとSQL自体の理解がおろそかになるから注意