Search code examples
ruby-on-railspostgresqleager-loading

Rails Specifying Conditions on Eager Loaded Associations


I have Users and Todos models, users have many todos and todo belongs to user and I need to find users who created a todo in the last day, if there is then send them an email. I've tried the query from the guide but it doesn't return any records even though there are because of (I think) the date format:

User.includes(:todos).where(todos: { created_at: 1.day.ago})

I've also tried:

User.includes(:todos).where(todos: { created_at: 1.day.ago.to_date})

and

User.includes(:todos).where(todos: { "date(created_at) = ?", 1.day.ago.to_date})

but the last one doesn't work: SyntaxError: unexpected '}', expecting end-of-input

I use Postgres, created_at is a datetime field (default rails timestamp)

in Psql:

created_at | timestamp without time zone | not null


Solution

  • As per the specifications in the post , you need to get the todos created on the past day, so

    the below mentioned query will not work

    User.includes(:todos).where(todos: { created_at: 1.day.ago.to_date})
    

    As 1.day.ago gives a particular timestamp and the database searches for the same timestamp ie including matching hours , minutes and seconds as well.

    So a better approach would be to search for the timestamp covering the whole day and thus provide range would be the best option.

    Modify the query as below mentioned:

    User.includes(:todos).references(:todos).where("todos.created_at >= ? and todos.created_at <= ?", 1.day.ago.beginning_of_day, 1.day.ago.end_of_day)
    

    This will fetch the todos created on the past day covering the whole day timings.