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

Rails: present?より便利なActiveSupportのpresenceメソッド(翻訳)

更新情報

  • 2018/09/27: 初版公開
  • 2021/02/26: 細部を更新

概要

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

日本語タイトルは内容に即したものにしています。

Rails: present?より便利なActiveSupportのpresenceメソッド(翻訳)

Active SupportはRubyのコアライブラリにメソッドをたくさん追加するので、何かと非難が集中します。特に評判がよろしくないのは、RubyのObjectクラスへのパッチです。

RubyのあらゆるオブジェクトはObjectのサブクラスなので、Objectクラスにメソッドを追加すればコードのあらゆるオブジェクトにそのメソッドが追加されることになります。

Active Supportでの拡張に関するドキュメントでもう少し詳しく見てみましょう。

そうしたメソッドのひとつが#presenceです。これはお馴染みの#blank?(訳注: #empty?のエイリアス)や#present?に比べて馴染みの薄いメソッドです。

次のように書くのではなく

変数の値を表示するのに、次のように長ったらしい条件を使う。

class User < ApplicationRecord
  validates :email, presence: true

  def friendly_name
    if nickname.present?
      nickname
    elsif given_name.present?
      given_name
    else
      email.split('@').first
    end
  end
end

次のように書く

Active Supportの#presenceメソッドを使う

class User < ApplicationRecord
  validates :email, presence: true

  def friendly_name
    nickname.presence || given_name.presence || email_local_part
  end

  private

  def email_local_part
    email.split('@').first
  end
end

そうする理由

#presenceメソッドは、オブジェクトが存在すればそのオブジェクトを返し、存在しなければnilを返したい場合にとても便利なショートカットです。

このメソッドは、Railsのビューでデータが存在するかどうかをチェクする部分でよく見かけるobject.present? ? object : nilという書き方と同等です。

このメソッドは、文字列や配列が空の場合にも有用なソリューションです。空の場合には#presencenilを返します。

そうしない理由があるとすれば

#presenceメソッドはRailsでしか利用できません。Rubyだけを使う場合、このメソッドのためだけにActive Supportをインクルードするほどの価値はおそらくないでしょう。

Railsを使う場合でも、既存のRubyクラスを拡張するこうしたRailsの習慣に抵抗を覚えるのも無理もないかもしれません。

自分のコードでモンキーパッチを使って既存クラスを改変する場合、標準のRubyクラスが思わぬ振る舞いを示すときにバグを踏みやすくなります。この種のコーディングスタイルで悩ましいのは、主にこうした点です。

モンキーパッチによる落とし穴が心配になってしまうと、たとえRailsが当てるパッチであっても避けたい気持ちになるかもしれません。

Railsのライブラリセットはしっかりメンテされていて広く用いられているので、私はこうしたパッチは安全とみなして、コードをきれいに書ける方を選びます。

関連記事

Rails: ActiveRecordのスコープで`present?`を使うとパフォーマンスが落ちることがある(翻訳)

Rails: pluckでメモリを大幅に節約する(翻訳)


CONTACT

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