Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I validate start date and end date?

What's the best way to validate that the end date is not before the start date, and start date is after the end date in Rails?

I have this in my view controller:

<tr>
    <td><%= f.label text="Starts:" %></td>
    <td><%= f.datetime_select :start_date, :order => [:day, :month, :year]%></td>
</tr>
<tr>
    <td><%= f.label text="Ends:" %></td>
    <td><%= f.datetime_select :end_date,:order => [:day, :month, :year]</td>
</tr>

I want it to come up with a popup of sorts, with a meaningful message.

I would like to make a generic method that takes two parameters, start and end date, which I then can call in my viewcontroller ; fx in the code above. Or, do I need to use jQuery instead?

like image 478
jacob Avatar asked Aug 30 '12 14:08

jacob


Video Answer


4 Answers

@YaBoyQuy client-side validation can work and avoids a hit to the server...

The question is also about end_date being after the start, so the validation - using gem date_validator - should also state

validates :end_date, presence: true, date: { after_or_equal_to:  :start_date}

The suggestion of

on: :create

would be incorrect for the end_date validation; logically this should also be run on an edit.

I upvoted on the basis of the succinct syntax.

like image 168
Jerome Avatar answered Oct 27 '22 08:10

Jerome


Clean and Clear (and under control?)

I find this to be the clearest to read:

In Your Model

validates_presence_of :start_date, :end_date

validate :end_date_is_after_start_date


#######
private
#######

def end_date_is_after_start_date
  return if end_date.blank? || start_date.blank?

  if end_date < start_date
    errors.add(:end_date, "cannot be before the start date") 
  end 
end
like image 23
Joshua Pinter Avatar answered Oct 27 '22 09:10

Joshua Pinter


Avoid client side validation, because it only validate client side... Use the rails validaters built in.

  validates :start_date, presence: true, date: { after_or_equal_to: Proc.new { Date.today }, message: "must be at least #{(Date.today + 1).to_s}" }, on: :create
  validates :end_date, presence: true
like image 5
YaBoyQuy Avatar answered Oct 27 '22 10:10

YaBoyQuy


If you want client side validation, use jQuery.

Or in rails, to validate server side, you could create your own I guess?

def date_validation
  if self[:end_date] < self[:start_date]
    errors[:end_date] << "Error message"
    return false
  else
    return true
  end
end

Rails >= 7.0 makes this a one-liner

validates_comparison_of :end_date, greater_than_or_equal_to: :end_date

PR, Rails Guides

like image 2
veritas1 Avatar answered Oct 27 '22 09:10

veritas1