Trying to create a result set of joined tables inside rails controller

I’m trying to create a result set of posts that have payments less than 30 days old So far I have something that needs correcting:

@posts=Post.joins(:payments).where(:payments.created_at > Time.now - 30 days)

Try this instead:

@posts = Post.joins(:payments).where('payments.created_at > ?', Time.now - 30.days)

When this query executes, RoR will:

  • Invoke Time.now to get the current time (and date)
  • Invoke the Numeric#days method to create an ActiveSupport::Duration object
  • Subtract the duration from the current time
  • Replace the question mark in the quoted string with the “30 days ago” time value
  • Add the SQL fragment to the query
  • Store the query in the @posts variable

@djmolny’s answer is great :slight_smile: There’s a few extra things you can do to really lean on ActiveRecord and Rail’s time helpers:

@posts = Post.joins(:payments).where.not(payments: { created_at: ..30.days.ago })

A bit of a mind job. For something like this I usually like to play around in rails c to make sure the query looks good.

Above, I’ve used where.not which inverts the concept "give me all the records created at up to 30 days ago. The ..30.days.ago is a range starting at infinity (low) and ending at 30 days ago. You can nest Ruby hashes to define where clauses without falling back to string interpolation. 30.days.ago is part of a large suite of Rails time helpers that are great to use :slight_smile:

Hope that helps :smiley:

  • Invoke the Numeric#days method to create an ActiveSupport::Duration object
  • Subtract the duration from the current time
  • Replace the question mark in the quoted string with the “30 days ago” time value
  • Add the SQL fragment to the query stick legacy 2
  • Store the query in the @posts variable