Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

あまり知られてないRuby/Railsの便利メソッド5つ(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。


  • 2017/11/30: 初版公開
  • 2022/05/06: 更新

あまり知られてないRuby/Railsの便利メソッド5つ(翻訳)

私がRuby on Railsで開発するようになってかれこれ数年が経過しましたが、Ruby世界で何か新しい発見があるたびに感動があります。それこそがRubyであり、Rubyは開発者を幸せにするのが目的です(他にもいろいろ法則はありますが、とりわけ)。Rubyを使っていると、毎年何か新しいものを見つけるたびにそのことを感じます。

本記事では最近私が発見したものをいろいろご紹介いたします。これらはめったに使われていませんし、使わなければいけないものでもありません。ほとんどは「シンタックスシュガー」ですが、いずれにしろコードがとても明確になります。一部は最近のRubyやRailsの新機能です。

🔗 1. Hash#dig

Rails開発を7年続けていますが、つい最近初めてこれを見かけたときに当然「これは何?」と思いました。私がRubyで開発を始めた頃は1.8だったのですが、この機能は2.3で導入されました。

次のようなコードを何回書いたか覚えていますか。

... if params[:user] && params[:user][:address] && params[:user][:address][:somewhere_deep]

digはsafe navigation演算子(ぼっち演算子)&.の一種ですが、Hashオブジェクトで使えます。これを使えば上のコードは次のように書き直せます。

... if params.dig(:user, :address, :somewhere_deep)

🔗 2. Object#presence_in

これは、Query Objects in Ruby on Railsというお気に入りの記事を書いたときに見つけました。存在チェックの結果(論理値)が欲しいのではなく、チェックされたオブジェクトそのものが欲しい場合に、条件(多くは三項演算子)を1つのメソッドで書けます。次のコードをご覧ください。

sort_options = [:by_date, :by_title, :by_author]
...

sort = sort_options.include?(params[:sort])
  ? params[:sort]
  : :by_date

# もうひとつの方法
sort = (sort_options.include?(params[:sort]) && params[:sort]) || :by_date

上のコードを下のように書き直せまず。ずっとよくなりましたよね?

params[:sort].presence_in(sort_options) || :by_date

🔗 3. Module#alias_attribute

この便利さに気づいたのは、ある案件でレガシーなデータベースを扱っているときでした。そのデータベースのあるテーブルでは、SERNUM_0ITMDES1_0といった気持ち悪いカラム名が大量に使われていました。このテーブルをActiveRecordモデルにマップするときに、WeirdTable.where(SERNUM_0: '123')のようなクエリやスコープを書く代わりに、#alias_attributeを使うことにしました。このメソッドのよさは、述語メソッドやゲッターやセッターを生成するだけではなく、クエリで次のように使える点です。

alias_attribute :name, :ITMDES1_0
...
scope :by_name, -> (name) { where(name: name) }

🔗 4. Object#presence

このメソッドは他のものよりは知られています。ApiDockにわかりやすい説明があります。object.presenceは次と同等です。

object.present? ? object : nil

🔗 5. Module#delegate

理由はわかりませんが、このメソッドを使っている開発者をめったに見かけません。このメソッドの主な目的は、癒着を弱めてデメテルの法則に沿うようにすることです。デメテルの法則についての良記事はいろいろありますが、その中でもAvdi Grimm氏の「デメテルは単なるよいアイデアではない: 法則である」が思い出されます。Rails Best Practicesの記事でも、デメテルの法則を適用するときに#delegateを使っているものがありますのでご覧ください。以下のスニペットでもおわかりいただけます。

class Profile < ApplicationRecord
  belongs_to :user

  delegate :email, to: :user
end

...
profile.email # profile.user.emailと同等

本記事でご紹介したヒントがお役に立てば幸いです。楽しくコーディングしましょう!

本記事を気に入っていただいた方は、ぜひ元記事の[✋]をクリックして応援してください。

関連記事

RailsのObject#tryがダメな理由と効果的な代替手段(翻訳)

3年以上かけて培ったRails開発のコツ集大成(翻訳)

Rails: dry-rbでForm Objectを作る(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。