0

「hh:mm:ss」形式の文字列を秒に変換するために、ActiveRecord の属性アクセサーをオーバーライドしています。これが私のコードです:

class Call < ActiveRecord::Base
  attr_accessible :duration

  def duration=(val)
    begin
      result = val.to_s.split(/:/)
             .map { |t| Integer(t) }
             .reverse
             .zip([60**0, 60**1, 60**2])
             .map { |i,j| i*j }
             .inject(:+)
    rescue ArgumentError
      #TODO: How can I correctly report this error?
      errors.add(:duration, "Duration #{val} is not valid.")
    end
    write_attribute(:duration, result)
  end

  validates :duration, :presence => true,
                       :numericality => { :greater_than_or_equal_to => 0 }

  validate :duration_string_valid

  def duration_string_valid
    if !duration.is_valid? and duration_before_type_cast
      errors.add(:duration, "Duration #{duration_before_type_cast} is not valid.")
    end
  end
end

検証中にこのエラーについて意味のあるレポートを作成しようとしています。私が思いついた最初の 2 つのアイデアは、コード サンプルに含まれています。

  1. アクセサーオーバーライド内のエラーに追加する - 動作しますが、それが良い解決策であるかどうかはわかりません。
  2. 検証方法を使用しduration_string_validます。他の検証が失敗したかどうかを確認し、duration_before_type_cast について報告します。このシナリオduration.is_valid?では有効な方法ではなく、期間が他の検証を通過したことを確認する方法がわかりません。
  3. duration=(val) 内にインスタンス変数を設定し、 内でレポートすることができduration_string_validます。

これがこの操作の良い方法であるかどうか、およびエラー報告をどのように改善できるかについて、フィードバックをお待ちしております。

4

1 に答える 1