almo
almo

Reputation: 6387

Rails 6 ActiveRecord sum columns in where clause

I have a Rails 6 app and a tabele with a scheduled_at and a duration (in minutes) column.

I want to get all records where scheduled_at + duration.minutes > Time.current.

Ideally I would have an ends_at columns, but unfortunately I don't.

Is there a way how to do this?

Upvotes: 1

Views: 233

Answers (3)

max
max

Reputation: 102443

You can use the function make_interval to create an interval from a column value (or any integer really):

Model.where(
   "scheduled_at + make_interval(mins := models.duration::INTEGER) > current_timestamp" 
)

# Or if you want to use your Rails servers notion of "now":
Model.where(
   "scheduled_at + make_interval(mins := models.duration::INTEGER) > ?", Time.current 
)

:= is the Postgres syntax for named notation which is similiar to keyword arguments in Ruby.

If you want to have a ends_at in the result you can select it:

Model
 .select(
   Model.arel_table[:*],
   "scheduled_at + make_interval(mins := models.duration::INTEGER) AS ends_at" 
 )
 .where(
   "ends_at > current_timestamp" 
 )

Upvotes: 1

Mshka
Mshka

Reputation: 1828

You can use the interval of postgresql then add 1 minute multiplied by your duration

Record.where("(scheduled_at + INTERVAL '1' MINUTE * duration) > ?", Time.current)

Make sure your duration is an integer tho

Upvotes: 3

Eyeslandic
Eyeslandic

Reputation: 14910

You can make use of the INTERVAL method in Postgres and compare that to the current time with NOW

Model.where("scheduled_at + INTERVAL '? minutes' > NOW()", 10)

# or ...
Model.where("scheduled_at + INTERVAL '? minutes' > ?", 10, Time.current)

Upvotes: 1

Related Questions