Rails: beforeバリデーションをやめてセッターメソッドにしよう(翻訳)

概要

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

Rails: beforeバリデーションをやめてセッターメソッドにしよう(翻訳)

以下のようなコードは多くのプロジェクトで目にします。

class Something
  before_validation :strip_title

  def strip_title
    self.title = title.strip
  end
end

しかし、この要件を満たす書き方は他にもあるのです。

class Something
  def title=(val)
    @title = val.strip
  end
end

あるいは以下のようにも書けます。

class Something
  def title=(val)
    self['title'] = val.strip
  end
end

.あるいは以下のようにも。

class Something
  def title=(val)
    super(val.strip)
  end
end

クラス内でのデータ保持方法に応じたものを選べばよいのです。さまざまなgemでさまざまな方法が使われています。

私がこの書き方を好む理由は以下のとおりです。

  • valnilの場合にコケる。そう、そして私はこれがよいことだと思っています。自分たちのフロントエンド側からnilがタイトルとして送信されることなどめったにないので、たまたまnilになったときに何かがコケて例外を発するのは問題ありません。いずれにしろこんなことはまず起こりません。私のプログラマーとしてのトカゲ脳はひととおりのエッジケースを察知していますし、私のトカゲ脳のこういうところが大好きです。しかしこのトカゲ脳がごくたまに私を裏切って、まず起こりえないようなエッジケースに焦点を合わせてしまうことがあります。
  • マジックが少なくて済む。Railsバリデーションのコールバックはクールですし、何度となく使ってきました。だからといって、スペースを取り除くのにわざわざコールバックを持ち出す必要はありません。
  • 利用範囲が広い。フィールドに値を設定した後に、途中でsaveなどしなくても、またはバリデーションを(何らかの理由で)実行しなかった場合でも、フィールドを読み出すときに動作してくれます。
something.code = " 123 "
something.code
# => 123

something.save(validate: false)

私は、Command ObjectForm Objectといった境界を超える用途に使われるオブジェクトに対して、バリデーションを消し去るルールを挿入する手法が特に気に入っています。

まとめ

以上で、ささやかなレッスンはすべて終了です。もっとお知りになりたい方は、元記事末尾のメーリングリストに加入いただくか、私どものFearless Refactoringの購入をぜひお願いします。

関連記事

Rails tips: 知らないと損する4つのバリデーションレベル(翻訳)

Rails: :before_validationコールバックの逸脱した用法を改善する(翻訳)

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ