はじめに
自分用のメモになります。
結論
find_byなどのnilを返すメソッドをscopeに設定しない
なぜなら
モデルのscopeでnilが返される条件が発生すると、該当のscope検索結果を無視した、クエリを発効してしまう。
Humanモデル
human.rb
class Human < ApplicationRecord
enum :gender, { male:0, female: 1}
scope :find_gender, -> (gender) { find_by(gender: gender) }
scope :tall_people, -> {where("height > ? ", 160)}
end
DB
class CreateHumen < ActiveRecord::Migration[7.0]
def change
create_table :humen do |t|
t.string :name
t.integer :height
t.integer :gender, default: 0, null: false
t.timestamps
end
end
end
コンソールの結果
irb(main):006:0> Human.find_gender("male").count
Human Load (0.2ms) SELECT "humen".* FROM "humen" WHERE "humen"."gender" = ? LIMIT ? [["gender", 0], ["LIMIT", 1]]
Human Count (0.3ms) SELECT COUNT(*) FROM "humen"
=> 7
irb(main):007:0> Human.all.count
Human Count (0.2ms) SELECT COUNT(*) FROM "humen"
=> 7
"male"は見つからないため、find_byではnilが返される。
scope内でnilが返されたため、scopeの条件は無視されて、実行される。
全てのレコードの数を検索した場合と同じ結果が加勢される
参考