10

I am trying to find records by 'created_at' date - the database column type is 'datetime' and I am using the UI DatePicker from jQuery

my url look like this: "localhost:3000/users_supported?selected_date=2012-10-31"

So far i am doing good :) and my query in controller looks like this:

@support_histories = current_agent.support_histories.where(:created_at => Date.parse(params[:selected_date]))

How to properly extract records by 'date' only from the 'datetime' db column

I tried doing this in Rails Console, but no luck there:

sh = SupportHistory.where(:created_at => DateTime.parse('2012-10-31'))
sh = SupportHistory.where(:created_at => Date.parse('2012-10-31'))
sh = SupportHistory.where(:created_at => DateTime.strptime('2012-10-31', '%Y-%m-%d'))

I got records if i do like mentioned below, but that's not useful to me as i am trying to find record by 'date' not by 'DateTime'

sh = SupportHistory.where(:created_at => '2012-10-31 19:49:57')
Syed
  • 15,657
  • 13
  • 120
  • 154

5 Answers5

35
selected_date = Date.parse(params[:selected_date])
# This will look for records on the given date between 00:00:00 and 23:59:59
sh = SupportHistory.where(
       :created_at => selected_date.beginning_of_day..selected_date.end_of_day)

Time Zones may be a concern you need to look into, but this should work if all your times are in the same time zone.

Jason Noble
  • 3,756
  • 19
  • 21
  • 1
    I have no words to thank you but i have to say I LOVE YOU ;) - i am New to coding and was trying to do this entire day :) I still would like to know - is there a way to query db excluding time ? – Syed Nov 04 '12 at 04:46
  • Section 2.2.2 of http://guides.rubyonrails.org/active_record_querying.html is similar to the answer I gave. You could probably do something creative like `select("date(created_at) as ordered_date).where(:ordered_date => ____)` but I like the `beginning_of_day..end_of_day` solution. – Jason Noble Nov 04 '12 at 15:40
  • This is such an elegant, Railsy solution. :) – Constant Meiring Dec 02 '17 at 16:48
2

A simple solution I use sometimes is to cast the date(time) field as text on the database rather than parse the string into date on application side. For your case that would be:

where('CAST(created_at AS text) LIKE ?', params[:selected_date])

Might not be the most effective on the database (depending on the context you use it in) but saves a lot of pita on the application side.

silverdr
  • 1,978
  • 2
  • 22
  • 27
2

Your current query doesn't work because you are querying a date on a datetime column. Those are two different data types.

For a datetime column, you'll need a datetime filter. You can do this by passing a DateTime object to the where clause. However, in your case you want records for the entire day so you'll specify a range between 00:00:00 and 23:59:59.

Before Rails 5.1:

SupportHistory.where(created_at: date.beginning_of_day..date.end_of_day)

Rails 5.1 and onwards: (this will generate the exact same range using #all_day)

SupportHistory.where(created_at: date.all_day)
Marco Prins
  • 7,189
  • 11
  • 41
  • 76
1

I solved this problem by creating a method in model like below, Say, my model is ticket.rb

 def created_date
   self.created_at.to_date
 end

then I queried like this,

 selected_date = Date.parse(params[:date])

 Ticket.all.map{|t| t if t.created_date == selected_date}.compact

This gives me accurate results that matches with the chosen date by the user.

Abhiram
  • 1,459
  • 14
  • 23
  • 3
    This is not a good way to do it because "Ticket.all" gets all the tickets in the table and expands them into an Array in memory. Bad for memory consumption and performance. Also, instead of doing "map" followed by "compact" (most likely looping through the entire ticket collection twice!), just use the "select" method, which filters the collection in one pass. But in the end, Jason Noble's answer above is the right way to do it, as "where" does not expand everything into memory the way "all" does. – David Escobar Apr 01 '16 at 23:19
0

If you want to parse a specific datetime

SupportHistory.where("created_at>=?", DateTime.parse('10 Dec 2021 11:54:00 PST -08:00'))
Taimoor Changaiz
  • 10,250
  • 4
  • 49
  • 53