【Rails】データが1件でもあるかどうかチェックするには`Model.exists?`
Ruby on Railsでデータベースにデータが存在するかどうかチェックしたい場合があると思います。
- そもそもデータがあるかどうか知りたい時
- ログインしたユーザーが管理者ユーザーがどうかをチェックしたい
そんな時はModel.exists?()
を使いましょうって話です。
データが存在するかチェックする
> User.exists? User Exists (3.0ms) SELECT 1 AS one FROM "users" LIMIT $1 [["LIMIT", 1]] => true
Userモデルにデータが1件でも存在するかのチェックです。
条件付きで存在をチェックする
> User.exists?(id: [1, 2, 3], name: 'opiyo', role: 'admin') User Exists (0.6ms) SELECT 1 AS one FROM "users" WHERE "users"."id" IN ($1, $2, $3) AND "users"."name" = $4 AND "users"."role" = $5 LIMIT $6 [["id", 1], ["id", 2], ["id", 3], ["name", "opiyo"], ["role", "admin"], ["LIMIT", 1]] => false
Userモデルから管理者ユーザーを探すような条件を渡してます。条件は何個でもつけれますし、配列も渡せちゃいます。
find_byも同じ使い方出来るじゃね?
データを1件だけ取得するのに便利なのがModel.find_by()
だと思うのですが、exists?
と同じような使い方ができますね。
> User.find_by(id: [1, 2, 3], name: 'opiyo', role: 'admin') User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" IN ($1, $2, $3) AND "users"."name" = $4 AND "users"."role" = $5 LIMIT $6 [["id", 1], ["id", 2], ["id", 3], ["name", "opiyo"], ["role", "admin"], ["LIMIT", 1]] => nil
さっきのと全く同じ条件ですが戻り値が違いますね。今回はnil
です。
取得できた場合はデータが1件取れますね。
> User.find_by(name: 'opiyo', role: 'admin') User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."name" = $1 AND "users"."role" = $2 LIMIT $3 [["name", "opiyo"], ["role", "admin"], ["LIMIT", 1]] => #<User id: 175, created_at: "2018-05-28 02:59:58", updated_at: "2019-06-18 05:42:19", name: "opiyo", role: "admin">
データも欲しいけど存在チェックもしたいっていう贅沢な事をする場合は、こんな書き方で叶えることが出来るので便利!
> if user = User.find_by(name: 'opiyo', role: 'admin') * puts user.name * puts user.role * end User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."name" = $1 AND "users"."role" = $2 LIMIT $3 [["name", "opiyo"], ["role", "admin"], ["LIMIT", 1]] opiyo admin
取得に失敗した場合はuser = nil
になりますが、nil
はfalse
なのでif文に入りません。
> if user = User.find_by(name: 'opiyoopiyo', role: 'admin') * puts user.name * puts user.role * end User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."name" = $1 AND "users"."role" = $2 LIMIT $3 [["name", "opiyoopiyo"], ["role", "admin"], ["LIMIT", 1]] => nil
さっき出力された、opiyo
とadmin
が表示されませんね。