改良中...フォームのエラー表示も含めた検証(validate)に変更
前回からの改良作業の続き。気付いたところから、より使い易く、よりメンテし易くなるようにどんどん変更していく。今回は、伝票と明細の合計金額の検証のところ。現状は検証エラーが発生しても、エラーメッセージしか表示しない。改良後は伝票の合計金額と、入力のある行の明細の金額で、お馴染みの赤枠で囲う強調表示もするようにしてみた。
- journals_valid?、journals_total_yenメソッドを定義することで、コードが理解し易くなった気がする。
# モデル: app/models/slip.rb class Slip < ActiveRecord::Base has_many :journals, :order=>:position, :dependent=>:destroy validates_presence_of :number, :executed_on, :total_yen def validate # 明細の入力チェック errors.add_to_base("明細が一行も入力されていません。") unless journals_valid? # 合計金額のチェック # nilが含まれると数値として取り扱えないので、to_iで数値に変換しておく必要あり errors.add(:total_yen, "が明細の合計と一致していません。") unless total_yen.to_i == journals_total_yen end def journals_valid? @editing_journals.inject(false) {|result, journal| result || journal.input?} end def journals_total_yen @editing_journals.sum {|journal| journal.yen.to_i} unless @editing_journals.blank? end ...(中略)... end
# モデル: app/models/journal.rb class Journal < ActiveRecord::Base belongs_to :slip validates_presence_of :comment, :yen def validate errors.add(:yen, "が合計金額と一致していません。") unless slip.total_yen.to_i == slip.journals_total_yen end ...(中略)... end
- 最初、以下のようにSlipモデルの中で明細(Journalインスタンス)の検証をしていた。しかし、これだと思った通りの検証結果にならない...。(journal.valid?を実行する時、それまでの検証エラーが一旦クリアされるため?)上記のように、Journalインスタンスの検証はJournalモデルの中で処理することで、うまく動くようになった。
# モデル: app/models/slip.rb
class Slip < ActiveRecord::Base
...(中略)...
def validate
unless total_yen.to_i == journals_total_yen
errors.add(:total_yen, "が明細の合計と一致していません。")
@editing_journals.each do |journal|
journal.errors.add(:yen, "が合計金額と一致していません。") if journal.input?
end
end
end
...(中略)...