1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Ruby(Rails)でどうやってSQLを作成するの?

Last updated at Posted at 2021-08-09

ActiveRecordと呼ばれるものでSQLを発行しています。

「RubyとSQLの翻訳機」みたいなもの
Railsでモデルを定義するだけで簡単にSQLを発行することができる
※モデル:データベースにアクセスする為に準備するためのクラス

image.png

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自体の理解がおろそかになるから注意

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?