公開日: | 最終更新日:
【Rails】 exists?メソッドの使い方~present?との違い
exists?メソッドとは、指定した条件のレコードがデータベースに存在するかどうかを真偽値で返すメソッドです。存在すればtrueを存在しなければfalseを返します。
1
オブジェクト.exists?(条件)
例えば、以下のようにexists?メソッドの引数に条件を指定すると、条件にマッチするレコードがあればtrue
を返し、レコードがなければfalse
を返します。
1
2
3
4
5
6
7
[1] pry(main)> User.exists?(name: '田中')
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '田中' LIMIT 1
=> true
[2] pry(main)> User.exists?(name: '林')
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '林' LIMIT 1
=> false
上記のように、usersテーブルのnameカラム
の値が"田中"
のレコードは存在しますが、nameカラム
の値が"林"
のレコードは存在しないのでfalse
を返します。また、引数の条件はハッシュ以外にも配列や整数なども使うことが出来ます。
基本的な使い方
この章では、existsメソッドの基本的な使い方について解説します。
exists?メソッドの定義方法
exists?メソッドの定義方法は、主に以下の3つの方法があります。
1
2
3
4
5
6
7
8
9
10
11
[1] pry(main)> User.exists?(1) # 引数に確認したいレコードの条件を指定
SELECT 1 AS one FROM `users` WHERE `users`.`id` = 1 LIMIT 1
=> true
[2] pry(main)> User.exists?(name: '田中') # 引数に確認したいレコードの条件を指定
User Exists (0.6ms) SELECT 1 AS one FROM `users` WHERE `users`.`name` = '田中' LIMIT 1
=> true
[3] pry(main)> User.where(name: '田中').exists? # whereメソッドで条件を絞り込んで確認
User Exists (0.4ms) SELECT 1 AS one FROM `users` WHERE `users`.`name` = '田中' LIMIT 1
=> true
上記のコードは、exists?メソッドの引数に条件を渡す2つの定義方法とwhereメソッドで条件を絞り込んで、exists?
メソッドでレコードがあるか確認する定義方法です。
それでは、この3つの定義方法を1つずつ順番に解説します。
指定したidのレコードを確認する
exists?メソッド
の引数に整数
を渡すと、指定した整数の主キーを持つレコードを確認します。
1
2
3
[1] pry(main)> User.exists?(1)
SELECT 1 AS one FROM `users` WHERE `users`.`id` = 1 LIMIT 1
=> true
指定した条件のレコードを確認する
exists?メソッド
の引数にハッシュ(カラム名: '値'
)を渡すと、その条件に一致するレコードの存在を確認します。
1
2
3
[2] pry(main)> User.exists?(name: '田中')
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '田中' LIMIT 1
=> true
以下のコードのように、複数の要素を条件に指定することも出来ます。発行されるSQLは条件の前後にANDが使われているので、どちらの条件も満たすレコードが存在する場合、trueを返します。
1
2
3
[2] pry(main)> User.exists?(name: '斎藤', age: 30)
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '斎藤' AND `users`.`age` = 30 LIMIT 1
=> true
また、以下のようにハッシュの値に配列で複数の値を渡すことも出来ます。この場合に、発行されるSQLはIN句が使われているので、どちらか一方の条件を満たすレコードが存在する場合、trueを返します。
1
2
3
[2] pry(main)> User.exists?(name: ['林','斎藤'])
SELECT 1 AS one FROM `users` WHERE `users`.`name` IN ('林', '斎藤') LIMIT 1
=> true
上記のコードは、name
カラムの値が"林"
、もしくは"斎藤"
にマッチするレコードがあるか確認します。
以下のように、nameカラムの値が"林"
のレコードは存在しませんが、"斎藤"
のレコードは存在するのでtrue
を返します。
絞り込みと併用する
exists?メソッドは、以下のコードのようにwhereメソッドと併用して使うことが出来ます。
1
2
3
[3] pry(main)> User.where(name: '田中').exists?
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '田中' LIMIT 1
=> true
上記のコードは、以下のexists?メソッドの引数に条件を入れた場合と同じ結果(true
)を得ることが出来ます。
1
2
3
[2] pry(main)> User.exists?(name: '田中')
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '田中' LIMIT 1
=> true
発行しているSQLは同じですが、この2つのコードは、exists?メソッドの引数に条件を指定しているかwhereメソッドで条件を絞り込んでいるかが違いますね。
もう少し詳しく解説すると、前者のUser.where(name: '田中').exists?
は絞り込みをかけたwhereの存在チェックを行っています。後者のUser.exists?(name: '田中')
は、カラムに指定したデータのユーザーがいるか存在チェックを行っています。
複雑な条件を絞り込んで、そのレコードに対して存在チェックを行いたい場合は前者の方がよく使われます。
条件文
exists?メソッドは真偽値を返すので、if文を使って指定した条件のレコードがある場合とない場合で処理を分けることが出来ます。
1
2
3
4
5
if モデル名.exists?(条件)
# 条件に指定したレコードが存在する場合の処理
else
# 条件に指定したレコードが存在しない場合の処理
end
例えば、usersテーブルのnameカラムの値が"斎藤"
のレコードが存在すれば、「斎藤という名前のユーザーは存在します。」を返し、レコードが存在しなければ「斎藤という名前のユーザーは1件も存在しません。」を返す場合は、以下のように記述します。
1
2
3
4
5
6
7
[1] pry(main)> if User.exists?(name: '斎藤')
[1] pry(main)* '斎藤という名前のユーザーは存在します。'
[1] pry(main)* else
[1] pry(main)* '斎藤という名前のユーザーは1件も存在しません。'
[1] pry(main)* end
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '斎藤' LIMIT 1
=> "斎藤さんという名前のユーザーは存在します。"
三項演算子
先ほどのif文の例は、以下のように三項演算子に書き換えることが出来ます。
1
2
3
4
#【三項演算子の構文】 条件式 ? レコードがある場合の処理 : レコードがない場合の処理
[2] pry(main)> User.exists?(name: '斎藤') ? '斎藤さんという名前のユーザーは存在します。' : '斎藤さんという名前のユーザーは存在しません。'
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '斎藤' LIMIT 1
=> "斎藤さんという名前のユーザーは存在します。"
このように、三項演算子を使うことで1行でコードをシンプルに記述することが出来ます。
後置if
true
を返した場合だけ何か処理を行う際は、後置if
で簡単に記述する事ができます。
1
2
3
4
5
# filename: コンソール | 後置ifを使った例
#【後置ifの構文】 trueの場合の処理 if 条件式
[3] pry(main)> '斎藤さんという名前のユーザーは存在します。' if User.exists?(name: '斎藤')
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '斎藤' LIMIT 1
=> "斎藤さんという名前のユーザーは存在します。"
上記は、usersテーブルにnameカラムの値が"斎藤"
のレコードが存在した場合に「斎藤さんという名前のユーザーは存在します。」を実行します。
後置unless
false
を返した場合だけ何か処理を行う際は、後置unless文でシンプルに1行で記述する事ができます。
1
2
# 【後置unlessの構文】falseの場合の処理 unless 条件式
'検索したユーザーはみつかりませんした' unless User.exists?(name: params[:q])
上記のparams[:q]
は、ユーザー検索で送信されたパラメーターが入ります。これを条件に指定することで、usersテーブルのnameカラムに検索したユーザー名のレコードがなければ文言を表示させる処理を行えます。
引数
exists?
メソッドの引数に渡すことが出来る形式は、以下の5つあります。
形式 | 内容 | 使用例 |
---|---|---|
整数(Integer) | 指定した整数の主キーを持つレコードを確認する | User.exists?(1) |
文字列(String) | 指定した文字列に対応する主キーのレコードを確認する | User.exists?("1") |
ハッシュ(Hash) | 指定したハッシュの条件に合うレコードを確認する | User.exists?(name: "斎藤") |
配列(Array) | 検索スタイルの条件を配列に指定する事が出来る | User.exists?(['name = ?', '斎藤']) |
引数なし | モデルの後に引数なしでexists?メソッドを使った場合、テーブルが空か確認する | User.exists? |
参考: API dock exists?
それでは、1つ1つの形式を確認します。
整数(Integer)
exists?メソッドの引数に 整数を渡すと、指定した整数の主キーを持つレコードを確認します。
1
モデル名.exists?(整数)
1
2
3
4
5
6
7
[1] pry(main)> User.exists?(1)
SELECT 1 AS one FROM `users` WHERE `users`.`id` = 1 LIMIT 1
=> true
[2] pry(main)> User.exists?(100)
SELECT 1 AS one FROM `users` WHERE `users`.`id` = 100 LIMIT 1
=> false
文字列(String)
exists?メソッドの引数に 文字列を渡すと、この文字列に対応する主キーのレコードを確認します。
1
モデル名.exists?("文字列")
1
2
3
4
5
6
7
8
# filename:コンソール | 引数に文字列を渡してidのレコードを確認する
[1] pry(main)> User.exists?("1")
SELECT 1 AS one FROM `users` WHERE `users`.`id` = 1 LIMIT 1
=> true
[2] pry(main)> User.exists?("100")
SELECT 1 AS one FROM `users` WHERE `users`.`id` = 100 LIMIT 1
=> false
以下のような文字列を渡した場合は、主キーが0(id = 0
)のレコードを確認してfalse
を返します。
1
2
3
4
# filename:コンソール | 引数の文字列が主キーに対応しないためfalseを返す
[3] pry(main)> User.exists?("aaa")
SELECT 1 AS one FROM `users` WHERE `users`.`id` = 0 LIMIT 1
=> false
ハッシュ(Hash)
exists?メソッドの引数に ハッシュを渡すと、その条件に一致するレコードの存在を確認します。
1
モデル名.exists?(Hash)
1
2
3
4
# filename:コンソール | 引数に渡したHashの条件に一致するレコードがあるか確認する
[1] pry(main)> User.exists?(:name => "斎藤")
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '斎藤' LIMIT 1
=> true
上記のコードは、ハッシュロケット(=>
)を使った古い書き方なので、以下のようにキーをシンボルにしてハッシュロケットを省略する事が出来ます。
1
2
3
4
# filename: コンソール | キーをシンボルにしてハッシュロケットを省略する
[2] pry(main)> User.exists?(name: "斎藤")
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '斎藤' LIMIT 1
=> true
ハッシュロケットやシンボルについては、ハッシュのキーにシンボルを使う方法を参照してください。
配列(Array)
exists?メソッドの引数には、配列で検索スタイルの条件を渡す事が出来ます。
1
モデル名.exists?([検索スタイル])
例えば、以下のコードのようにプレースホルダー(?
)を使った検索スタイルの条件を配列で渡す事が出来ます。nameカラムの値が"斎藤"
のレコードの存在を確認します。
1
2
3
4
5
# filename:コンソール | 配列にプレースホルダーを使った例
# 最初の要素の「?」に'斎藤'が入る
[1] pry(main)> User.exists?(['name = ?', '斎藤'])
SELECT 1 AS one FROM `users` WHERE (name = '斎藤') LIMIT 1
=> true
また、以下のコードのようにexists?
メソッドの引数に配列を使えば、LIKE句であいまい検索をする事が出来ます。
1
2
3
4
5
6
7
8
# filename: コンソール | exists?メソッドであいまい検索をする場合
[2] pry(main)> User.exists?(['name LIKE ?', "%斎%"])
SELECT 1 AS one FROM `users` WHERE (name LIKE '%斎%') LIMIT 1
=> true
[3] pry(main)> User.exists?(['name LIKE ?', "%あ%"])
SELECT 1 AS one FROM `users` WHERE (name LIKE '%あ%') LIMIT 1
=> false
1番目のコードは、nameカラムに「斎」の値があるレコードを検索し、斎藤さんのレコードがあるのでtrue
を返します。2番目のコードは、nameカラムに「あ」の値があるレコードを検索していますが、存在しないのでfalse
を返します。
引数なし
以下のように、モデル名の後に引数なしでexists?メソッドを使った場合、テーブルにレコードが存在していればtrue
を返し、レコードが存在していなければfalse
を返します。
1
モデル名.exists?
1
2
3
4
# filename:コンソール | usersテーブルにレコードが存在するか確認する
[1] pry(main)> User.exists?
SELECT 1 AS one FROM `users` LIMIT 1
=> true
また、以下のようなwhereメソッドで条件を絞り込んで、exists?メソッドでその条件のレコードが存在するか確認するというパターンは良く利用します。
1
2
3
4
5
6
7
[2] pry(main)> User.where(name: '斎藤').exists?
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '斎藤' LIMIT 1
=> true
[3] pry(main)> User.where(name: '遠藤').exists?
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '遠藤' LIMIT 1
=> false
上記のコードは、以下のwhereメソッドを使わない場合と同様の結果(true
)が返ります。
1
2
3
[1] pry(main)> User.exists?(name: '田中')
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '田中' LIMIT 1
=> true
どちらも同じSQLが発行されていますが、前者の引数がないexists?は
exists?メソッドには二つの使い方があります。
引数がある場合と引数がない場合です。
実際にコードを見て比べてみましょう。
1
2
3
[1] pry(main)> User.where(name: '田中').exists?
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '田中' LIMIT 1
=> true
上記の引数がない場合は、nameが田中さんのユーザーが存在するかどうかをbooleanで返しています。これはUser.where(name: '田中')
のレシーバーに対して存在するかどうかをexists?で返していることになります。
対して引数がある場合はどうでしょう?
1
2
3
[1] pry(main)> User.where(nickname: '田中').exists?(created_at: Date.yesterday..Date.today)
User Exists (0.7ms) SELECT 1 AS one FROM `users` WHERE `users`.`nickname` = '田中' AND `users`.`created_at` BETWEEN '2020-06-07' AND '2020-06-08' LIMIT 1
=> false
上記の引数がある場合を比べてみると、User.where(nickname: '田中')のレシーバーのデータが昨日 ~ 今日に作成されていれば true, そうでなければfalseを返すようにしています。
つまりexists?の引数がある場合とない場合の違いは、レシーバーのオブジェクトが存在するか?と、レシーバーのオブジェクトに対してさらにexists?の引数に指定した条件のオブジェクトが存在するかの違いになります。
present?メソッドとの違い
present?メソッドは、使用したオブジェクトが空ではないか存在チェックしてくれるメソッドです。
以下のように記述する事で、present?メソッドでもレコードの存在確認をすることが出来ます。
1
2
3
4
5
6
7
[1] pry(main)> User.exists?(name: '斎藤')
SELECT 1 AS one FROM `users` WHERE `users`.`name` = '斎藤' LIMIT 1
=> true
[2] pry(main)> User.find_by(name: '斎藤').present?
SELECT `users`.* FROM `users` WHERE `users`.`name` = '斎藤' LIMIT 1
=> true
どちらのメソッドもレコードの存在をチェックしますが、場面によっては使い分けが必要です。
present?メソッドを使う場面
present?メソッドは、以下のようにpresent?メソッドでレコードの存在確認を行った後に、インスタンスを使って何か処理をしたいときに使用します。
1
2
3
4
5
6
user = User.find_by(name: params[:user][:name])
if user.present?
redirect_to user_path(user), notice: "#{user.name}さん。のプロフィールページへようこそ"
else
redirect_to root_path, alert: "#{params[:user][:name]}さんのプロフィールは見つかりませんでした。"
end
上記のコードでは、ユーザー検索で送信されたパラメータをfind_byメソッドで検索して、そのレコードがあれば、レコード(Userモデルのインスタンス)をuser
に格納します。レコードがなければ、user
にはnil
が入ります。
そして、present?メソッドで存在チェックを行います。インスタンスが存在すれば、そのインスタンスを使ってユーザーのページにredirect_toメソッドで遷移させて、存在しなければルートへ遷移します。
このように、レコードの存在チェックを行った後にインスタンスを使って何か処理をする場合はexists?メソッドではなくpresent?メソッドを使います。
present?メソッドについて詳しい解説は、「present?メソッドの使い方」を参考にしてください。
exists?メソッドを使う場面
exists?メソッドは、以下のように存在チェックの後にインスタンスを使う必要がなく、レコードの存在チェックだけを行う場合に使用します。
1
2
3
4
5
if User.exists?(name: params[:user][:name])
"#{params[:user][:name]}さんは登録されています。"
else
"#{params[:user][:name]}さんは未登録です。"
end
上記は、ユーザー検索で送信されたパラメータのレコードの存在チェックを行っています。
レコードが存在すれば、パラメータの名前で登録していることを出力させて、レコードが存在しなければ、未登録だということを出力します。
このように、インスタンスを使わずにレコードの存在チェックだけ行う場合はexists?メソッドを使用します。
これまで学習したRuby on Railsについて体系的に整理したい場合は、こちらの書籍が参考になりますよ!
応用的な使い方
この章ではexists?メソッドの応用的な使い方について解説します。
自作メソッドの作成方法
exists?メソッドを利用した自作メソッドを作成し、リファクタリングする方法を解説します。
以下は、ownersテーブルとcatsテーブルとdogsテーブルで、テーブル同士の関連付け
が行われています。
この3つのテーブルに対応するOwnerモデルとCatモデルとDogモデルには、それぞれ以下のようにアソシエーションが定義されています。
1
2
3
4
class Owner < ApplicationRecord
has_many :cats
has_many :dogs
end
1
2
3
class Cat < ApplicationRecord
belongs_to :owner
end
1
2
3
class Dog < ApplicationRecord
belongs_to :owner
end
上記のアソシエーションは、「1人の飼い主(Owner)は、複数の猫/犬を飼い、1匹の猫(Cat)/犬(Dog)は、1人の飼い主に属する関係」です。アソシエーションの詳しい解説は、「アソシエーションを図解形式で理解する!」を参考にしてください。
それでは、このデータを使って解説していきます。
メソッドを作成
田中さんと加藤さんが猫を飼っているか調べたい場合は、以下のようにアソシエーションとexists?メソッドで記述することが出来ます。
1
2
3
4
5
6
7
8
9
[1] pry(main)> Owner.find_by(name: '田中').cats.exists?
SELECT `owners`.* FROM `owners` WHERE `owners`.`name` = '田中' LIMIT 1
SELECT 1 AS one FROM `cats` WHERE `cats`.`owner_id` = 1 LIMIT 1
=> true
[2] pry(main)> Owner.find_by(name: '加藤').cats.exists?
SELECT `owners`.* FROM `owners` WHERE `owners`.`name` = '加藤' LIMIT 1
SELECT 1 AS one FROM `cats` WHERE `cats`.`owner_id` = 4 LIMIT 1
=> false
上記のコードは、以下の画像のように、田中さんの猫のレコードは存在するのでtrue
を返し、加藤さんの猫のレコードは存在しないのでfalse
を返します。
つまり、catsテーブルの外部キー制約のカラム(owner_id
)に、飼い主の主キーのレコードが存在すればtrue
を返し、レコードが存在しなければfalse
を返します。
1
2
Owner.find_by(name: '田中').cats.exists?
Owner.find_by(name: '加藤').cats.exists?
上記のコードは、調べる飼い主が違うだけで.cats.exists?
のコードは同じです。
このような場合は、同じような処理が2つ並んでいると冗長なので、以下のようにowner.rb
にhave_cat?
メソッドを定義することで、処理をまとめることが出来ます。
1
2
3
def have_cat?
cats.exists?
end
メソッド作成時の注意点ですが、exists?メソッドの返り値は真偽値なので、メソッド名の最後に必ず「?」をつけましょう。
理由としては、Owner.find_by(name: '田中').have_cat?
とメソッドを呼び出した際に、have_cat?に対する返り値がtrue
なら猫を飼っていて、false
なら猫を飼っていないという事がメソッド名から読み取ることが出来るからです。
?を付けないからと言ってエラーになることはありませんが、真偽値を返す場合のメソッド名の最後に「?」をつける事で、メソッド名だけで処理の内容を理解することが出来るので可読性もあがります。
自作メソッドでリファクタリング
先ほど作成したhave_cat?メソッドを使って、以下のコードをリファクタリングします。
1
Owner.find_by(name: '田中').cats.exists?
このコードにhave_cat?メソッドを使うと、以下のように記述することが出来ます。
1
2
3
4
[4] pry(main)> Owner.find_by(name: '伊藤').have_cat?
SELECT `owners`.* FROM `owners` WHERE `owners`.`name` = '伊藤' LIMIT 1
SELECT 1 AS one FROM `cats` WHERE `cats`.`owner_id` = 2 LIMIT 1
=> true
メソッドを使うことで、コードも短くなり可読性が上がります。
また、以下のように後置unlessを使って、加藤さんの飼い猫がいなければ文言を出力することも出来ます。
1
2
3
4
[5] pry(main)> '猫可愛いですよ〜!飼います?' unless Owner.find_by(name: '加藤').have_cat?
SELECT `owners`.* FROM `owners` WHERE `owners`.`name` = '加藤' LIMIT 1
SELECT 1 AS one FROM `cats` WHERE `cats`.`owner_id` = 4 LIMIT 1
=> "猫可愛いですよ〜!飼います?"
|| 演算子を併用する
|| 演算子は、左から順番にtrue
であるか判定していて、false
が出れば一つ右の式をtrueか判定してと繰り返して、trueが出ればその式は真になります。
1
2
3
4
[1] pry(main)> number = 100
=> 100
[2] pry(main)> number == 10 || number == 20 || number == 100
=> true # number == 100がtrueになるので、式全体がtrueになる
exists?メソッドや作成したhave_cat?メソッドのように、真偽値を返すメソッドと||演算子
を併用することで簡潔なコードを書くことが出来ます。
例えば、以下のように犬も猫も飼っていない吉田さんのようなownerに対して、何か処理を行う場合を想定します。
吉田さんが猫も犬も飼っていなければ、「ペットを飼いましょう」と出力する場合は、以下のように|| 演算子
に加えて後置unless
を使うことでより簡潔に記述出来ます。
1
2
3
4
5
6
7
[6] pry(main)> owner = Owner.find_by(name: '吉田')
Owner Load (0.4ms) SELECT `owners`.* FROM `owners` WHERE `owners`.`name` = '吉田' LIMIT 1
[6] pry(main)> 'ペットを飼いましょう!' unless owner.have_cat? || owner.dogs.exists?
SELECT 1 AS one FROM `cats` WHERE `cats`.`owner_id` = 5 LIMIT 1
SELECT 1 AS one FROM `dogs` WHERE `dogs`.`owner_id` = 5 LIMIT 1
=> "ペットを飼いましょう!"
上記の||演算子
の箇所では、吉田さんは猫を飼ってないのでowner.have_cat?
の式でfalseを返し、右のowner.dogs.exists?
の式を判定します。犬も飼ってないのでfalse
を返し式全体がfalseになります。
そして、上記の画像のように式全体がfalseになったことで、unlessでfalseの場合の「ペットを飼いましょう」という処理が実行されます。
1
'ペットを飼いましょう!' unless owner.have_cat? || owner.dogs.exists?
上記のコードを再確認すると、have_cat?メソッド同様に.dogs.exists?
もメソッドに処理をまとめることが出来るので、以下のようにowner.rb
にhave_dog?
メソッドを定義します。
1
2
3
def have_dog?
dogs.exists?
end
have_dog?メソッドを使うと、以下のようにコードの可読性が上がります。
1
'ペットを飼いましょう!' unless owner.have_cat? || owner.have_dog?
上記のコードは、ownerがペットを飼っているか確認しているので、以下のhave_pet?
メソッドをowner.rb
に定義し処理をまとめることによって、更にリファクタリングすることが可能です。
1
2
3
def have_pet?
have_cat? || have_dog? # have_cat?がfalseならhave_dog?を判定する
end
have_pet?メソッドを使うと、以下のように簡潔に記述することが出来ます。
1
2
3
4
[9] pry(main)> 'ペットを飼いましょう!' unless owner.have_pet?
SELECT 1 AS one FROM `cats` WHERE `cats`.`owner_id` = 5 LIMIT 1
SELECT 1 AS one FROM `dogs` WHERE `dogs`.`owner_id` = 5 LIMIT 1
=> "ペットを飼いましょう!"
リファクタリング前のコードと比べると、以下のようにコードが短くなり可読性が上がります。
1
2
3
4
5
# リファクタリング前
'ペットを飼いましょう!' unless owner.have_cat? || owner.dogs.exists?
# リファクタリング後
'ペットを飼いましょう!' unless owner.have_pet?
真偽値を返す処理がある際は、||演算子
と併用することで、このように可読性のある便利なメソッドを作成することが出来ます。
この記事のまとめ
- exists?メソッドとは、指定した条件のレコードがデータベースに存在するかどうかを真偽値で返すメソッド
- レコードが存在すればtrueを存在しなければfalseを返す
- exists?メソッドの引数に渡すことが出来る形式は、整数、文字列、ハッシュ、配列、引数なしがある