You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When passing an ActiveSupport::Duration to an Active Record where query on Postgres, it will be converted to an ISO 8601 string in a hash condition on an interval column, but not in an array condition.
For interval columns, it would be convenient to be able to pass ActiveSupport::Duration in either hash or array conditions. However, some applications probably depend on the existing behavior to pass ActiveSupport::Duration as a numeric type so any change might have to be opt-in.
Steps to reproduce
# frozen_string_literal: truerequire"bundler/inline"gemfile(true)dosource"https://rubygems.org"git_source(:github){ |repo| "https://github.com/#{repo}.git"}gem"rails",github: "rails/rails",branch: "main"gem"pg"gem"byebug"endrequire"active_record"require"minitest/autorun"require"logger"# docker run --rm -e POSTGRES_PASSWORD=postgres -p 9999:5432 postgresActiveRecord::Base.establish_connection("postgres://postgres:postgres@localhost:9999/postgres")ActiveRecord::Base.logger=Logger.new(STDOUT)ActiveRecord::Schema.definedocreate_table:movies,force: truedo |t|
t.interval:runtimeendendclassMovie < ActiveRecord::BaseendclassBugTest < Minitest::Testdeftest_durationMovie.create!(runtime: 2.hours)Movie.create!(runtime: 90.minutes)Movie.create!(runtime: 3.hours + 30.minutes)# SELECT COUNT(*) FROM "movies" WHERE "movies"."runtime" < $1 [["runtime", "PT3H"]]assert_equal2,Movie.where(runtime: ...3.hours).count# SELECT COUNT(*) FROM "movies" WHERE (runtime < 10800)# ActiveRecord::StatementInvalid: PG::UndefinedFunction: ERROR: operator does not exist: interval < integerassert_equal2,Movie.where('runtime < ?',3.hours).countendend
Expected behavior
When passing a duration in an array condition, it should be converted to a valid interval input (e.g., ISO 8601)
@ghiculescu opened a PR here #44438. However, I'm not sure of the process for breaking changes, please let me know if I need to include a deprecation notice in the PR or create a separate PR with the deprecation notice, etc.
When passing an
ActiveSupport::Duration
to an Active Recordwhere
query on Postgres, it will be converted to an ISO 8601 string in a hash condition on aninterval
column, but not in an array condition.For
interval
columns, it would be convenient to be able to passActiveSupport::Duration
in either hash or array conditions. However, some applications probably depend on the existing behavior to passActiveSupport::Duration
as a numeric type so any change might have to be opt-in.Steps to reproduce
Expected behavior
When passing a duration in an array condition, it should be converted to a valid interval input (e.g., ISO 8601)
https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-INTERVAL-INPUT
Actual behavior
The duration get converted to an integer seconds which Postgres can't cast to an interval.
System configuration
Rails version:
Using rails 7.1.0.alpha from https://github.com/rails/rails.git (at main@6a55aff)
Ruby version:
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]
The text was updated successfully, but these errors were encountered: