0

私はbefore_validationモデルを持っています。その目的は、2 つのオブジェクト間の作業時間を計算し、その値を属性DateTimeに挿入することです。time_workedその成功は 2 つのフィールドの有効性に依存し、3 番目のフィールドの値を吐き出し、それが検証されます。

class TimeEntry < ActiveRecord::Base
  validates :start_time, :end_time, :presence => true
  validates :time_worked, :presence => true, :numericality => true
  before_validation :calculate_time_worked

def calculate_time_worked
    time_float = (Time.parse(self.end_time.to_s) - Time.parse(self.start_time.to_s)) / 1.hour  
    self.time_worked = ((time_float * 10).ceil).to_f/10
end

問題は、または のいずれかが空または無効なcalculate_time_worked場合、メソッドが失敗することです。これがまさに、これら 2 つのフィールドに検証がある理由です!start_timeend_time

リファクタリングする方法はありますか?

4

2 に答える 2

1

この場合、@PedroMedeiros の before_save ソリューションが機能します....しかし、time_worked が正であることを検証したい場合は、おそらく次のようにします。

  validate :calculate_time_worked

  def calculate_time_worked
    return if end_time.blank? || start_time.blank?
    time_float = (Time.parse(self.end_time.to_s) - Time.parse(self.start_time.to_s)) / 1.hour  
    self.time_worked = ((time_float * 10).ceil).to_f/10
    if time_worked < 0
      self.errors.add(:end_time, "Must be after Start Time")
    end
  end

最後に、この SO の質問は、時間の差を取得するのにクールです

于 2012-06-21T19:36:00.620 に答える
0

これらのメソッドが設定される直前に before_validates が呼び出されることがわかります。私があなたの場所なら、before_save を使用して calculate_time_worked を使用します。attrs が設定され、検証が完了すると。

class TimeEntry < ActiveRecord::Base
  validates :start_time, :end_time, :presence => true
  validates :time_worked, :presence => true, :numericality => true
  before_save :calculate_time_worked

end
于 2012-06-21T19:27:03.343 に答える