メソッド名の末尾に?
が付くメソッド(勝手に?系メソッドと呼びます)がたくさんありすぎてよく分からなくなったのでまとめました。
Ruby
Rubyのメソッド。true/falseを返します。
# nil? > nil.nil? => true > ''.nil? => false > [].nil? => false # empty? > [].empty? => true > {}.empty? => true > ''.empty? => true > ' '.empty? => false > nil.empty? => NoMethodError # include? > [1,2,3].include?(2) => true 'abc'.include?('b') => true
Object#nil? (Ruby 3.2 リファレンスマニュアル)
String#empty? (Ruby 3.2 リファレンスマニュアル)
Array#include? (Ruby 3.2 リファレンスマニュアル)
Rails
Railsのメソッド。true/falseを返します。
# blank? > nil.blank? => true > [].blank? => true > {}.blank? => true > ''.blank? => true > ' '.blank? => true # present? > nil.present? => false > [].present? => false > {}.present? => false > ''.present? => false > ' '.present? => false
バリデーション
Railsのバリデーションのチェックで使用します。true/falseを返します。
valid?
: バリデーションがパスするか?invalid?
:!valid?
(valid?
の反対)
save
やcreate
メソッド実行時に行われるバリデーション処理のみを実行するイメージ。
- バリデーションエラーの場合はerrorsオブジェクトにエラーが入る
- エラーは
インスタンス.errors.full_messages
で取得できる
# valid? * class Book < ApplicationRecord * validates :title, presence: true > end => {:presence=>true} > Book.new(title: nil).valid? => false > Book.new(title: 'book_name').valid? => true # invalid? Book.new(title: nil).invalid? => true > Book.new(title: 'book_name').invalid? => false
Active Record バリデーション - Railsガイド
ActiveRecord
RailsのActiveRecordで使えるメソッドです。
exists?
persisted?
exists?
レコードを存在確認します。true/falseを返します。
- 引数に該当した時点で検索は終了する。
- 全件取得する
present?
よりパフォーマンスが高い。 - IN句検索: 条件のカラムの値を配列で複数指定する。どちらかにマッチすればtrueを返す。
- AND句検索: 条件のカラムを複数指定する。両方にマッチすればtrueを返す。
# exists? > User.exists?(51) # idで検索 User Exists? (0.3ms) SELECT 1 AS one FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 51], ["LIMIT", 1]] => true > User.exists?(name: nil) User Exists? (0.3ms) SELECT 1 AS one FROM "users" WHERE "users"."name" IS NULL LIMIT ? [["LIMIT", 1]] => false > User.exists?(name: 'karlley') User Exists? (0.3ms) SELECT 1 AS one FROM "users" WHERE "users"."name" = ? LIMIT ? [["name", "karlley"], ["LIMIT", 1]] => true # exists? とpresent? のSQLの比較 > User.where(name: 'karlley').exists? # EXISTS?句で検索 User Exists? (1.8ms) SELECT 1 AS one FROM "users" WHERE "users"."name" = ? LIMIT ? [["name", "karlley"], ["LIMIT", 1]] => true > User.where(name: 'karlley').present? # WHERE句で検索 User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."name" = ? [["name", "karlley"]] => true # カラムの値を複数指定して検索(IN句で検索) > User.exists?(id: [1,2]) User Exists? (0.3ms) SELECT 1 AS one FROM "users" WHERE "users"."id" IN (?, ?) LIMIT ? [["id", 1], ["id", 2], ["LIMIT", 1]] => true > User.exists?(id: [1,nil]) User Exists? (0.4ms) SELECT 1 AS one FROM "users" WHERE ("users"."id" = ? OR "users"."id" IS NULL) LIMIT ? [["id", 1], ["LIMIT", 1]] => true # カラムを複数指定して検索(AND句) > User.exists?(name: 'karlley', id: 51) User Exists? (0.3ms) SELECT 1 AS one FROM "users" WHERE "users"."name" = ? AND "users"."id" = ? LIMIT ? [["name", "karlley"], ["id", 51], ["LIMIT", 1]] => true > User.exists?(name: 'karlley', id: nil) User Exists? (0.3ms) SELECT 1 AS one FROM "users" WHERE "users"."name" = ? AND "users"."id" IS NULL LIMIT ? [["name", "karlley"], ["LIMIT", 1]] => false
Active Record クエリインターフェイス - Railsガイド
ActiveRecordでは present? の代わりに exists? を使おう - Qiita
exists? とpresent? の使い分け
レコードの存在チェックを行った後にインスタンスを使って何か処理をする場合はexists?メソッドではなくpresent?メソッドを使います。
exists?メソッドは...存在チェックの後にインスタンスを使う必要がなく、レコードの存在チェックだけを行う場合に使用します。
【Rails】 exists?メソッドの使い方~present?との違い | Pikawaka
返り値のオブジェクトを使って処理を行う/行わないで使い分けます。
- 返り値のインスタンスで処理を行う:
present?
- インスタンスに対して呼び出して検索する。
- 返り値のインスタンスで処理を行わない:
exists?
- モデルに対して呼び出して検索する(SQLを発行する)。
# exists? はインスタンスに対して呼び出せない > user = User.find_by(name: 'karlley') > user.present? => true > user.exists? => NoMethodError # インスタンスに対して呼び出せない # インスタンスを使って処理を行う: present? > user = User.find_by(name: 'karlley') * if user.present? * puts "#{user.name}のレコードは存在します。" * else * puts "#{user.name}のレコードは存在しません。" > end karlleyのレコードは存在します。 => nil # インスタンスを使って処理を行わない: exists? * if User.exists?(name: 'karlley') * puts "レコードは存在します。" * else * puts "レコードは存在しません。" > end User Exists? (0.4ms) SELECT 1 AS one FROM "users" WHERE "users"."name" = ? LIMIT ? [["name", "karlley"], ["LIMIT", 1]] # SQLが発行される レコードは存在します。 => nil
persisted?
レコードが保存済みなのかを確認します。true/falseを返します。
> user = User.new # saveしていない > user.persisted? => false > user = User.first # 既存レコード > user.persisted? => true
【Rails】DBに保存済みかどうかをチェックするpersisted?メソッドについて簡単に解説するよ|TechTechMedia
まとめ
頻出する?系メソッドだけですが情報を整理できてスッキリしました。 まだまだたくさんありそうなので見つけたら追記していこうと思います。
参照
Object#nil? (Ruby 3.2 リファレンスマニュアル)
String#empty? (Ruby 3.2 リファレンスマニュアル)
Array#include? (Ruby 3.2 リファレンスマニュアル)
Active Record バリデーション - Railsガイド
Active Record クエリインターフェイス - Railsガイド
ActiveRecordでは present? の代わりに exists? を使おう - Qiita
【Rails】 exists?メソッドの使い方~present?との違い | Pikawaka
【Rails】DBに保存済みかどうかをチェックするpersisted?メソッドについて簡単に解説するよ|TechTechMedia