Yaya
Yaya

Reputation: 291

How to get a model id from inside a validation method

In one of my validations, I would like to make sure that the user date range input is not overlapping with existing stored date-ranges:

class Timecard < ActiveRecord::Base
  validate :does_not_intersect_with_existing_timecards

  def does_not_intersect_with_existing_timecards
    if from_date && to_date &&
      !Timecard.where("? <= to_date AND ? >= from_date", from_date, to_date).empty?
      errors.add(:from_date, "must not intersect with existing timecards")
    end
  end
end

The problem is that this validation will fail if called from an update method (as the where clause will find the record currently being updated in the database). I do not want to only validate on: :create, since the user may edit the date range.

How can I exclude the current model from the validation query?

I don't seem to have access to id or @id from within the validation method...

Upvotes: 1

Views: 191

Answers (2)

Bachan Smruty
Bachan Smruty

Reputation: 5734

Have a try with this

def does_not_intersect_with_existing_timecards
  if self.new_record?  
     errors.add(:from_date, "must not intersect with existing timecards") if from_date && to_date && !Timecard.where("? <= to_date AND ? >= from_date ", from_date, to_date).empty?
  else
     errors.add(:from_date, "must not intersect with existing timecards") if from_date && to_date && !Timecard.where("? <= to_date AND ? >= from_date AND id != ?", from_date, to_date, self.id).empty?
  end

end

OR

def does_not_intersect_with_existing_timecards
   errors.add(:from_date, "must not intersect with existing timecards") if from_date && to_date && !Timecard.where("#{self.new_record? || 'id != ' + self.id.to_s} AND ? <= to_date AND ? >= from_date ", from_date, to_date).empty?
end

Upvotes: 2

Litmus
Litmus

Reputation: 10996

You can use before_save hook instead of validation

Upvotes: 1

Related Questions