Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails - Is a date between two dates?

I'm creating a system that needs to make sure planned "Trips" do not over lap. To do this I am trying to validate the start_date and end_date to make sure they are not within the start and end dates for another trip.

class TripdateValidator < ActiveModel::EachValidator

  def validate_each(object, attribute, value)

      # Check value exists as end_date is optional
      if value != nil

          parsed_date = Date.parse(value)

          # is the start date within the range of anything in the db
         trips = Trip.where(['start_date >= ? AND end_date <= ? AND user_id = ?', parsed_date, parsed_date, object.user_id])

        # overlapping other trips, aghhh
        object.errors[attribute] << 'oh crap' if trips
      end
  end
end

The date is coming from a type="date" field which is powered by jQuery UI Datepicker and contains the format 2011-01-01. This gets to rails as 2011-01-30 00:00:00 UTC which I don't fully understand.

If I try to use Date.parse() on this value it gives the error:

TypeError in TripsController#create

$_ value need to be String (nil given)

Rails.root:
/Users/phil/Sites/travlrapp.com
Application Trace | Framework Trace |
Full Trace

app/models/trip.rb:29:in
validate_each'
app/controllers/trips_controller.rb:75:in
create'
app/controllers/trips_controller.rb:74:in
`create'

Whenever I run the query, nothing is returned. Could this be a date format issue, is my logic broken or am I doing something really stupid? Been stuck on this a while and google is no help.

Edit People are focusing on the Date.parse error but that is not the main problem. Where im stuck is that I don't understand how to do date comparisons when everything is in totally different formats.

I have swapped Date.parse() for Chronic.parse() and now I am getting the following SQL queries generated:

 SELECT "trips".* FROM "trips" WHERE (start_date >= '2011-01-26 00:00:00.000000' AND end_date <= '2011-01-26 00:00:00.000000' AND user_id = 19)

This returns nothing. The dates I am testing against are:

start: 2011-02-17 00:00:00.000000 end: 2011-02-21 00:00:00.000000

Seeing as I think dates are being formatted properly now it seems more like a logic problem. How the heck can I validate overlapping dates >.

like image 234
Phil Sturgeon Avatar asked Jan 23 '11 16:01

Phil Sturgeon


2 Answers

Squeel power FTW!!! I'm sure you will love it

$ gem install squeel

model.rb

Model.where{date_colum > 10.years.ago & date_column < DateTime.now}
like image 105
Victor Hazbun Anuff Avatar answered Sep 20 '22 01:09

Victor Hazbun Anuff


For those that land here, check the Rails guides on Range conditions:

Client.where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight)

That will produce the following SQL:

SELECT * FROM clients WHERE (clients.created_at BETWEEN '2008-12-21 00:00:00' AND '2008-12-22 00:00:00')

So you can search for fields between two dates using a range.

like image 23
Paulo Fidalgo Avatar answered Sep 17 '22 01:09

Paulo Fidalgo