非ActiveRecordの検証エラーメッセージをローカライズする
ActiveRecordを継承しないクラスに対し、バリデーションとそのエラーメッセージをローカライズする方法。
(1)バリデーション機能を持つクラスの実装
ポイントは冒頭のmixin。これによりActiveRecordのような振る舞いが可能となり、validatesメソッドが使えるようになる。
また、後述のform_forヘルパーにこのクラスのインスタンスを渡すとpersisted?メソッドが呼び出されるので、persisted?の定義も必要。
class Import::CSV include ActiveModel::Validations include ActiveModel::Conversion attr_accessor :file validates :file, :presence => true def persisted?; false; end end
(2)ビューの実装
form_forの引数@csvは(1)のインスタンス。ポイントは特になく、いたって普通にActiveRecordのフォームを実装する感じで実装する。
<%= form_for(@csv, :url => import_csv_path, :multipart => true) do |f| %> <% if @csv.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@csv.errors.count, "error") %> prohibited this csv from being saved:</h2> <ul> <% @csv.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> <div class="field"> <%= f.label :file %> <%= f.file_field :file %> </div> <div class="actions"> <%= f.submit 'confirm' %> </div> <% end %>
(3)ロケールファイルの実装
ポイントはActiveRecordではなく、ActiveModelをmixinしたクラスなのでキーはactivemodel配下に設定すること。それ以外はActiveRecordと同様。
尚、本題から逸れるけどネームスペースを持つクラスは以下のようにスラッシュ(Import::CSV => import/csv)で表す。
ja: activemodel: attributes: import/csv: file: CSVファイル errors: messages: blank: "を入力してください。"
以上