ムカデノワラジ

ムカデノワラジ

ガジェット・Webサービス・プログラミング・エンタメについて書く雑記ブログ

MENU

nilClass errorを回避するrubyのtry, try!,present?, presenceメソッドと nil ガードの挙動まとめ

Object.try(:method_name)

nilでない場合

Object.method_nameを、

nilの場合(またはメソッドが存在しない場合)、nilを返す

Object.method_nameは使用されない、つまりnilClassのmethodを使うことにはならないため、エラーが回避できる

Object.try!(:method_name)

try!はObjectがnilかnot nilかのみを判断してくれる。NoMethodErrorを見落とさない。

Object.try(:method_name)が、Objectが存在する( not nil )か存在しない( nil )か、および、Objectがmethod_nameのメソッドを持つか持たないかを判断するのに対し、try!はObjectが存在する(nilではない)か存在しない(nil)かのみを判断する。

 

Object.tryがnilを返すのは

  1. Objectがnil
  2. Objectがmedhod_nameで指定されたmethodを持たない

場合である。

user.try(:name)としたときに確かめたいのはuserがnilかどうかの場合が多い。

しかし、ここでmethod名を間違えてuser.try(:no_existence_method_name)とすると、tryメソッドはuserがnil かどうかにかかわらずnilを返す。

try!(:no_existence_method_name)はNoMethodErrorを返す。

 

Object.present?

真偽値を返す。

Objectが存在する、かつ空でない場合のみtrue、それ以外はfalseを返す。

nil.present?    #=> false

[].present?    #=> false

[1].present?   #=> true

Object.presence

Objectが存在すればObject自身を、存在しなければnilを返す。

User.find_by(age: 20).presence

#=> User.find_by(age: 20)のレコードが存在するときはそのレコード(つまりUser.find_by(age: 20)自身)を、存在しなければnilを返す

そのためnilガードと合わせれば

user= User.find_by(age: 20).presence || "no user"

などと書ける。

nilガード

しばしば

User.name||="名無しの権兵衛"

のように省略して使われるが、実際の中身は

User.name || hoge="名無しの権兵衛"

右辺ではhogeに”名無しの権兵衛”を代入しhogeを返している。

したがってhogeで"名無しの権兵衛"を取得できる。

 

おまけ

findとfind_by_id

あるModelに id: 1が存在しないときの挙動の違い

Model.find(1)

#=> Error  ActiveRecord::RecordNotFound

 

Model.find_by_id(1)

#=> nil

 

find_by_id(n)の場合、errorではなくnilを返すため、try,presence,nilガードと使うとスッキリかけることがある。

ディヴァイン・グリモワール

あわせて読みたい

PAY.JPにitemやamountなどの独自のparamsを追加する - ムカデノワラジ

ruby on railsでリンク先のページでturbolinksを無効にする - ムカデノワラジ

Bulma・bootstrap以外のシンプルなCSSフレームワークまとめ - ムカデノワラジ