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 Traceapp/models/trip.rb:29:in
validate_each'
create'
app/controllers/trips_controller.rb:75:in
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 >.
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}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With