Rails: 2007年3月アーカイブ
Railsのscaffoldで使われているerror_messages_forってすっごく便利なのですが、
これリストの入力フォームに対応していないんですよね。

上記の画面には2行のテーブルがあって、
交通費、宿泊費、その他の3レコードが含まれています。つまり3×2で6レコードです。
普通にerror_messages_forだとチェック自体は行われますが、エラーメッセージが最後の1レコード分しか出ませんでした。
というわけで、すべてのレコードのエラーを拾って重複を排除して表示する用にしてみました。
app/helpers/application_helperにメソッドを追加してもいいんですが、最近ActiveHeartを入れたばかりなので、
vender/plugin/active_heart/lib/active_recorde_message_ja.rbのerror_messages_forの下に下記コードを追加しておきました。
def list_error_messages_for (object_name, options = {})
objects = instance_variable_get("@#{object_name}")
errors = Array.new
for record in objects
unless record.errors.empty?
record.errors.each_full { |msg| errors.push(msg)}
end
end
errors = errors.uniq
unless errors.empty?
options = options.symbolize_keys
content_tag("div",
content_tag(
options[:header_tag] || "h2",
"#{errors.size}個のエラーが発生しました"
) +
content_tag("p", "次の項目に問題があります") +
content_tag("ul", errors.collect { |msg| content_tag("li", msg) }),
"id" => options[:id] || "errorExplanation",
"class" => options[:class] || "errorExplanation"
)
end
end
ruby&rails初心者なので恥ずかしい限りですが、一応動作はしているみたいです。ツッコミ有ればご指導下さい。
つか、こんなのとっくに誰か作っている気もする。更に言えば確実に此処はRailsらしからぬ実装になってしまったかも。

エラーチェック自体は相変わらず適当(あえてエラー出しています)なのですが・・・
が、またしても此処で問題が。
詳細の項目には:allow_nilでnilやブランクの場合はチェックしないようにしているんですが、何故かチェックされてしまいます。他の所はちゃんと動作しているのに・・・
近々攻略予定です。
RailsのValidationを日本語化してみます。
使うのは、Rubyist Magazineで紹介されているActiveHeart。
Railsプロジェクトホームに移ってからsubversionを使ってインストール。
$ ./script/plugin install http://svn.rails2u.com/public/plugins/trunk/active_heart/
あとはサーバーを再起動するだけでOKです。
但し、これだけだと、

項目名が英語のまま。
これを日本語化するには、
class DailyExpense < ActiveRecord::Base set_field_names :description => '詳細', :amount => '金額', :currency_code => '通貨' validates_numericality_of :description, :on => :update, :allow_nil => true validates_numericality_of :amount, :on => :update, :allow_nil => true validates_numericality_of :currency_code, :on => :update, :allow_nil => true end
と、set_field_namesを付けてあげれば良いらしい。ktkr

validateの内容は適当なんで突っ込まないでください。
”詳細”が数値ってなんの詳細だよ・・・
ところで、validatesの:allow_nilオプションなんですが、これを付けるとnilの場合はvalidateおこなわないんですねぇ。
なんでこんな重要な事早く言わないかなぁ。APIドキュメント見るまで気がつかなかった。単に、AWDwRにのっていなかったのだけど、当時はなかったのか・・・
ちなみにerror_messages_forのリスト対応したんですけど、
もう少し見直したいので、明日書くことにします。
久しぶりにRailsをさわっていて気がついた。
validationってオブジェクトのコレクションに対応していないんではないか?
active_record_helper.rbに定義されているerror_messages_forの部分を読んでみると、
# file active_record_helper.rb, line 103
def error_messages_for(object_name, options = {})
options = options.symbolize_keys
object = instance_variable_get("@#{object_name}")
if object && !object.errors.empty?
content_tag("div",
content_tag(
options[:header_tag] || "h2",
"#{pluralize(object.errors.count, "error")} prohibited this
#{object_name.to_s.gsub("_", " ")} from being saved"
) +
content_tag("p", "There were problems with the following fields:") +
content_tag("ul", object.errors.full_messages.collect { |msg|
content_tag("li", msg) }),
"id" => options[:id] || "errorExplanation",
"class" => options[:class]
|| "errorExplanation"
)
else
""
end
end
やっぱりか・・・
これだけなら、ActionHelperに複数オブジェクト用のメソッドを定義すれば良いけど、
更にテーブルを結合している場合は、そもそも更新をどうすれば良いのだろう?
色々頭に方法は浮かぶけど、一番Railsらしい書き方に未だ至らず、現在朝の3時半。
くそぉ、明日やるか・・・
くやしい
くやしい
くやしい
くやしい
絶対明日攻略してやる!















