🙇

【備忘録】Railsで使う書き方①~Null条件演算子~

2022/06/01に公開

年明けからRubyとRailsを書き始め、気づいたら5ヶ月経過しました。

1日でも早く良いコードが書きたいと思う一方で、なかなか速度が上がらず、毎日悔しい思いをしています。

こうした毎日を過ごしていると次のようなコードを見かけるとすぐに反応するようになりました。

sample.rb
def user_exists?
   user = find_user
   if user
      true
   else
      false
   end
 end

こう書き換えたくなります。

sample.rb
def user_exists?
   !!find_user
 end

また他の言語にも言えることですが、次のような記述を見ると手が止まりません。

sample.rb
numbers = [1,2,3,4,5]
new_numbers = []
numbers.each { |n| new_numbers << n * 10 }

こう書き換えたくなります。

sample.rb
numbers = [1,2,3,4,5]
new_numbers = numbers.map { |n| n * 10 }

これくらいであればすぐに書き換えは思い浮かぶのですが、
なかなか書き換えが思い浮かばず時間を浪費することが多々あります。
今回はその時に使用したいイディオムをまとめたいと思います。

&.演算子

定番ですね。

sample.rb
def find_currency(country)
 currencies = { japan: 'yen', us: 'dollar', india: 'rupee'}
 currencies[country]
end

def show_currency(country)
 currency = find_currency(country)
 if currency
   currency.uncase
 end
end

このshow_currencyメソッドは次のように書き換えることができます。

sample.rb
def show_currency(country)
 currency = find_currency(country)
 currency&.uncase
end

次のように色々な記事がありますが、

https://qiita.com/yoshi_4/items/e987b698c1978d248cfc

今回の場合だと、currencynilが入った場合、uncase

sample.rb
undefined method `uncase' for nil:NilClass (NoMethodError) 

が発生します。これに対して$.演算子を使ってuncaseを呼び出すと、uncaseを呼び出したオブジェクトがnilでない場合は、その結果(今回は大文字)を、nilだった場合はnilを返します。

使用例

実際に使用した例は次のようなRailsのmodelに定義したクラスメソッドのケースです。

book.rb
class Book
  def self.expensive(price)
    where(price > 3000)
  end
end

Book.expensive(price)を呼び出し、該当しない場合は戻り値はnilになります。
この時Book.expensive(price).order(id: :desc)と書くとエラーになります。
これを避けるためにBook.expensive(price)&.order(id: :desc)と書きました。

ちなみに

book.rb
class Book
  scope :expensive, -> { where("price > ?", 3000) }
end

クラスメソッドではなくscopeで定義した時、結果がnilとなった場合は、
該当Scopeの検索条件を除外したクエリが発行されます。

色々と覚えることが多くて大変です。

参考文献

プロを目指す人のためのRuby入門[改訂2版] 言語仕様からテスト駆動開発・デバッグ技法まで

パーフェクト Ruby on Rails 【増補改訂版】

Discussion