ひびきの技術メモ帳

駆け出しエンジニアのメモ帳

nilを返すscope内の処理について

# app/model/user.rb
class User < ApplicationRecord
  # find_byで見つかった一番最初のインスタンスを返す、見つからなかったらnilを返す
  scope :find_name, ->(first_name) { find_by(first_name: first_name) }
  # whereで見つかったActiveRecord::Relationを返す
  # 見つからなかったら空のActiveRecord::Relationを返す 
  scope :search_name, ->(first_name) { where(first_name: first_name) }
end

scope内でfind_byを使っている時に条件に当てはまるものが見つからなかった場合はモデルの全てのインスタンスを返してしまう。

irb(main):011:0> User.find_name("存在しない名前")
=> #Userのインスタンスが全て返ってくる

scope内でwhereを使っている時に条件に当てはまるものがなかった時は#<ActiveRecord::Relation []>の空配列を返す

irb(main):012:0> User.search_name("存在しない名前")
=> #<ActiveRecord::Relation []>

スコープはActiveRecord::Relationを必ず返す仕様なので、nilではなくallと同じ結果のActiveRecordRelationを返してしまうらしい。

scopeにはActiveRecord::Relationを返すものを使いましょう。

ActiveRecord::Relationを返すメソッド

all, scope (実装でnilを返すとallと同様になる), select (使い方次第), group, order, reorder, unscope, joins, where, rewhere, having, limit, offset, lock, none, readonly, create_with, from, distinct, extending, reverse_order, includes, eager_load, preload, references, uniq, merge, except, only