user2622247
user2622247

Reputation: 1089

How to find record depending upon the updated_at in rails

I have to find the record depending upon their updated_at column. For this I am comparing updated_at with todays date. I tired in following ways but it wont worked

todays_date = Date.today.strftime("%m/%d/%Y")
obj = MyClass.where(:updated_at.strftime("%m/%d/%Y")=> todays_date )

But it is not working. How can I do this?

Upvotes: 1

Views: 4428

Answers (4)

Stanislav Timanov
Stanislav Timanov

Reputation: 1

Rails 5.2 + Postgresql MyClass.where("updated_at::Date = ?", date)

Upvotes: 0

Max Williams
Max Williams

Reputation: 32933

Bit of additional explanation which is too long for a comment:

You need to be clear about the difference between times in ruby and times in the database. In ruby, a time or date is an instance of a Time/Date object. You can convert it into a string with strftime as you are doing here.

In the database, it is stored as a string, effectively, though because the column type is set to datetime there are some extra functions you can call on it in SQL (this list of functions will vary depending on which DBMS you use - mysql, postgres etc). The format of the datetime string as it's stored in the database will, again, vary depending on the DBMS.

If you had todays_date as an actual date object (not a string), you can pass it straight through to .where, and rails will translate it into the appropriately fomatted string for the resulting sql query.

For example,

 my_date = Date.today #this is a Date object
 obj = MyClass.where(:updated_at => my_date)

at this point, rails builds an sql query. The query is just a string to be called in sql, so everything that isn't a string will get "translated" into string form. If the database column is a datetime

In mysql for example, the sql would be

select * from my_classes where updated_at = "2014-05-09";

Note that even though we passed a date through

When you translate the date into a string yourself, you are liable to not use the right format. Eg if you were to do this

obj = MyClass.where(:updated_at => my_date.strftime("%m/%d/%Y"))

then rails is already getting a string through as the value for the query, and it won't try and translate it. You'll end up with this sql:

select * from my_classes where updated_at = "09/05/2014;

and, because your database doesn't store dates in that format, you won't get any matches.

You can see how the date is translated into the db format by calling .to_s(:db) on it. What this reveals is the difference between dates and times:

Date.today.to_s(:db)
=> "2014-05-09"
Date.today.to_time.to_s(:db)
=> "2014-05-09 00:00:00"

It also reveals how greater-than/smaller-than comparison works: it's just string comparison! Because the dates and times are stored in order of most-significant-element-first (year, month, day, hour, minute, second), then date comparison is just string comparison. Ie, comparing "2012-10-15" and "2014-05-09" is just like comparing "abcdef" and "abcxyz" ("abcxyz" is 'higher' than "abcdef" because "x" is "higher" than "d").

This also allows comparison of dates and datetimes:

"2014-05-09 01:00:00" is "higher" than "2014-05-09", because if there's a "tie" between two strings up to the end of one of them, the one with more characters is deemed "higher". This is helpful, as any specific time on a given day is considered to be after (ie higher than) just the date of that day by itself.

Upvotes: 2

Rajesh Omanakuttan
Rajesh Omanakuttan

Reputation: 6918

You could simply use:

 obj = MyClass.where("updated_at >= ?",Date.today)

Can also use:

obj = MyClass.where("updated_at >= ?",Date.today.beginning_of_day)

Hope it helps :)

Upvotes: 1

Yosep Kim
Yosep Kim

Reputation: 2941

Try this code...

obj = MyClass.where("updated_at >= ? AND updated_at <= ?",Date.today.to_time.beginning_of_day,Date.today.to_time.end_of_day)

Your code below would not work, since :updated_at is a symbol not object (syntax error).

:updated_at.strftime("%m/%d/%Y")

Upvotes: 4

Related Questions