«

»

3月
11

Rails Sexy Validationとlibディレクトリ配下のオートロードについて

validates_xxx_ofはもう古いのか。

RoRのバリデーションについて調べているとSexy Validationという謎の言葉を見つける。手元にある参考書は4年前のもので古いので、もちろんそんなキーワードは載っていない。「は?セクシー?」ってフザケているのかと些か思いますが、どうもこちらの方が良さ気であります。

ということで、[rails3]Sexy Validationで独自のValidationをの記事を参考にvalidates_xxx_of に代わるRails3の新しいバリデーション Sexy Validation を試してみました。

例えば、nameという属性が空でないかチェックする場合、従来はvalidates_presence_ofというヘルパーを用いて

  validates_presence_of :name

という1行をモデルクラスに付け足していましたが、これと同等な機能をSexy Validationで行う場合は

  validates :name, :presence => true

となります。そして、独自のバリデーションを行うためには、

class HogeValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
  end
end

といった感じでvalidate_eachメソッドをオーバーライドしたクラスを用意した上で、

  validates :name,  :presence => true, :hoge => true

こんな風に追記すれば良い。なるほど、これはキレイ。

libへ外出し

元の記事にもありますが、やはりこれは別のソースファイルとして適切な場所に置きたい。コメントを見るとlibディレクトリに置いているという方がいたので、同じようにやってみる。自前のバリデーションのクラスを記述したrbファイルをlibディレクトリ配下に置く。
が、どうも上手くいかない。

バージョンの違い?

いくつかサイトを見てみると、どうやらRails3の場合は、明示的にapplication.rbに以下の記述が必要であることがわかりました。

application.rbへ追記(初期はconfig.autoload_pathsがコメントアウトになっている)

    config.autoload_paths += %W(#{config.root}/lib)
    config.autoload_paths += Dir["#{config.root}/lib/**/"]

参考) http://hemju.com/2010/09/22/rails-3-quicktip-autoload-lib-directory-including-all-subdirectories/

ただ、この対応は冒頭の記事のコメントとほぼ同じなので別の原因。

バージョンではなく規約?

参考のブログにはlazy loadという言葉があるのでauto load機能は遅延読み込みと関係していると思われる。この場合、ファイル名とクラス名(やモジュール名)に関連がないとフレームワークとしてはちょっと辛い?と思い、class HogeValidator に対して hoge_validator.rbという名前のファイル名にしてみたところ、無事認識された。ただ、勘なので合っているかは分からない。

すこし調べるとこんな記事を見つける。
Ruby/Ruby on Rails/libディレクトリとオートロードと自作ライブラリを見ると、そういう決まりと、凡そ、そんな実装になっている模様です。

開発環境Tips

ひとまずこれでlibに外出ししたクラス等をオートロードできる事が分かったので良かったのだが、一度ロードされてしまったものは、ソースを更新しても再起動しないと反映されないという問題がある。( 明示的にrequireした場合も同様 ) これについては、先程挙げたブログの別エントリーに良いソリューションがあるので、これを参考にしたいと思います。

http://hemju.com/2011/02/11/rails-3-quicktip-auto-reload-lib-folders-in-development-mode/

コメントを残す

メールアドレスは公開されません

次の HTMLタグおよび属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>