プログラミング備忘録

プログラミングの学習状況をメモしています

69日目

今日の学習

SQL

Railsでのクエリ

qiita.com

上記の記事から引用しながら、どのようなメソッドがあるのか、またそのメソッドはどのようなクエリに相当するのかを見ていきたい。

クエリの見方に慣れていないため、メソッドと併記することで慣れるのが目的。

最終的には、Railsチュートリアルサブセレクトを扱ったときのコードがちゃんと理解できるようになりたい。

そして、今後はログに出てくるSQL文をよく読むようにしたい。

ALLメソッド

これまでに一番良く使ってきたメソッドだろう。

User.all
=> SELECT "users".* FROM "users"

usersに含まれるすべてのデータを取得してくれる。

idnamecreated_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))

こちらは、Railsチュートリアルで見たものと同じ形だ。

クエリに限らず、プログラミング言語は同じ効果があるが複数の書き方があるというものが非常に多く、混乱してしまう。

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メソッドの役割

今もfindfind_byメソッドの違いが分からなくて、さらにwhereメソッドまで出てきて、それぞれどういった場面で使うべきか明確でなかったので調べる。

qiita.com

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を使って有効なユーザーのみを表示するようにしたり、ステータスフィードで特定のユーザーのポストを一覧表示する際に使用した。