69日目
今日の学習
SQL
Railsでのクエリ
上記の記事から引用しながら、どのようなメソッドがあるのか、またそのメソッドはどのようなクエリに相当するのかを見ていきたい。
クエリの見方に慣れていないため、メソッドと併記することで慣れるのが目的。
最終的には、Railsチュートリアルでサブセレクトを扱ったときのコードがちゃんと理解できるようになりたい。
そして、今後はログに出てくるSQL文をよく読むようにしたい。
ALLメソッド
これまでに一番良く使ってきたメソッドだろう。
User.all => SELECT "users".* FROM "users"
users
に含まれるすべてのデータを取得してくれる。
(id
やname
、created_at
といった情報)
whereメソッド
特定のデータのみ抽出したい場合に使用する。上の記事では、単一のテーブルからの条件付き取得と説明されている。
文字列指定とシンボル指定の2つの方法がある。
- シンボル指定
モデル名.where(カラム名: 条件) User.where(name: "長谷川") => SELECT "users".* FROM "users" WHERE "users"."name" = '長谷川'
- 文字列指定
モデル名.where("カラム名 = 条件") User.where("name = '長谷川'") => SELECT "users".* FROM "users" WHERE (name = '長谷川')
【Rails】 whereメソッドを使って欲しいデータの取得をしよう! | Pikawaka - ピカ1わかりやすいプログラミング用語サイト
こちらの記事では、プレースホルダについても触れてある。
2つの方法があるが、実際は1つの条件で検索をする際には`where(カラム名: "条件")のように、シンボル指定で定義をする。SQLインジェクションを防ぐためだ。ハッシュ形式で記述するとSQLインジェクションを防げる。
SQLインジェクションを防ぐ他の方法として、プレースホルダがある。
?
(プレースホルダー)は、第二引数で指定した値に置き換える。
モデル名.where("name =?", "長谷川") =>name = "長谷川"と同じ意味 # 下記のコードと同じ意味 モデル名.where("name = '長谷川') モデル名.where(name: "長谷川")
IN
where
メソッドの条件に配列を使うことで、複数の条件を定義することができる。
複数の値のどれかと一致するかという条件判定を行う。
IN
句を使うことで、複数の条件をまとめて指定することができる。
- シンボル
User.where(id: [1,2]) => SELECT "users".* FROM "users" WHERE "users"."id" IN (1, 2)
配列を使って取得すると、配列で指定したレコードが取得できる。
クエリを見てみると、IN
句が使われているのが分かる。
- 文字列
User.where("id IN (1, 2)") => SELECT "users".* FROM "users" WHERE (id IN (1, 2))
クエリに限らず、プログラミング言語は同じ効果があるが複数の書き方があるというものが非常に多く、混乱してしまう。
OR
複数カラム指定でor
を使うと、どちらかの条件に当てはまるレコードを取得できる。
例:name
カラムに長谷川
があるか、age
カラムに20
があるレコードを全て取得するコード
どちらか1つでも当てはまっていればレコードを取得
- シンボル
User.where(name: "長谷川").or(User.where(age: 20)) => SELECT "users".* FROM "users" WHERE ("users"."name" = "長谷川" OR "users"."age" = 20)
- 文字列
User.where("name = ? or age = ?", "長谷川", 20) => SELECT "users".* FROM "users" WHERE (name = "長谷川" or age = 20)
find, find_by, whereメソッドの役割
今もfind
とfind_by
メソッドの違いが分からなくて、さらにwhere
メソッドまで出てきて、それぞれどういった場面で使うべきか明確でなかったので調べる。
findメソッド
各モデルのidを検索キーとしてデータを取得するメソッド
id
以外での検索不可。主キーが一致するレコードを取得しているため。
id
が明確に分かっているケースで使用する。
find
でお馴染みのfind(params[:id])
では、具体的な数値が入るから使われていることが分かった。
find_by
各モデルをid以外の条件で検索するメソッド(idでも検索可能)
返ってくる結果は、最初にヒットした1件のみ 該当データがない場合は、nilが返ってくる。
id
以外の条件となっているが、id
でも検索可能なため、指定したカラムで検索と考えた方がよい。
Railsチュートリアルでは、主にパスワードやメールアドレスが一致しているかどうかをfind_by
で参照していた。
where
各モデルをid以外の条件で検索する場合 該当するデータ全てが返ってくる。
find_by
と違って、全てのレコードが取得できるため、使い分ける。
Railsチュートリアルでは、where
を使って有効なユーザーのみを表示するようにしたり、ステータスフィードで特定のユーザーのポストを一覧表示する際に使用した。