nil落ちの回避方法
findなどを使用した時に、レコードが存在しない場合NoMethodErrorが発生する。
そんな時に検索結果をnilで返したい時に行う方法を色々。
||=を使う
修正前
Userのidが存在しない場合NoMethodErrorが発生する。
@current_user = User.find(params[:id])
修正後
Userのidが存在しない場合@current_userはnilを返す。
@current_user ||= User.find(params[:id])
&.を使う(ぼっち演算子)
レシーバーが nil のとき,NoMethodErrorを投げずにnilを返してくれる機能。
@current_user = User&.find(params[:id])
メソッドやスコープにも使えるので、便利
user.rb
class User < ApplicationRecord
scope :find_user, -> { find(10) }
end
users_controller.rb
def show
@current_user = User&.find_user
end
tryを使う
レシーバーが nil のとき、NoMethodErrorを投げずにnilを返してくれる機能。
※定義されていないものを呼び出そうとした時、#try はnilを返すため注意が必要
user.rb
class User < ApplicationRecord
scope :find_user, -> { find(10) }
end
users_controller.rb
def show
@current_user = User.try(find_user)
end
まとめ
-
||=と&.を使う事で簡単にNoMethodErrorを回避できる。
参考資料
第8章 コラム8.1
https://railstutorial.jp/chapters/log_in_log_out?version=4.2