class Timesheet < ActiveRecord::Base
attr_accessible :status, :user_id, :start_date, :end_date, :activities_attributes
SUBMITTED = 'Submitted'
APPROUVED = 'Approuved'
REJECTED = 'Rejected'
STATUS_VALUES = [SUBMITTED, APPROUVED, REJECTED]
belongs_to :user
has_many :activities, dependent: :destroy, inverse_of: :timesheet
has_many :time_entries, through: :activities
accepts_nested_attributes_for :activities, allow_destroy: true
validates :status, presence: true, inclusion: {in: STATUS_VALUES}
validates :user_id, :start_date, :end_date, presence: true
validate :maximum_worktime_per_day
after_update :check_an_activity_present
private
def maximum_worktime_per_day
time_entries_by_date = time_entries.group_by(&:workdate)
time_entries_by_date.each do |key, value|
errors[:base] << "Maximum daily time should not exceed 1 day" if worktime_by_date(value) > 1
break
end
end
end
Here is a spec to test it:
describe "when worked time per day is greater than 1 day" do
it "should not be valid" do
new_timesheet = build(:submitted_timesheet)
activity = new_timesheet.activities.first
time_entry_1 = build(:time_entry, activity: activity, workdate: Date.today.beginning_of_week, worktime: 1.0)
activity_2 = build(:activity, timesheet: new_timesheet)
time_entry_2 = build(:time_entry, activity: activity_2, workdate: Date.today.beginning_of_week, worktime: 1.0)
expect(new_timesheet).to_not be_valid
end
end
I'd like just to validate that the maximum worked time per day should not greater than 1.0 (accepted values are 0.5 or 1.0 defined in TimeEntry model).
I create a new timesheet instance in a nested form. The error is never raised when creating a new tie sheet. But when editing it, the validation catches well the error even if I modify the wrong value or remove completely a nested instance. I have an impression that the collection is not refreshed before running the validation method.