This is related to this github issue, I would like to confirm if it is a bug or the expected behavior.
ActiveRecord#merge
not uses the table alias.
It makes the query throw an ActiveRecord::StatementInvalid
when it is built using the following pattern:
- (A) joins an aliased relation
has_one :singular_name
belongs_to :singular_name
has_many :custom_name, class: "TheModel"
- (B) uses a condition referring the aliased relation
where(singular_name: {id: 1})
order(singular_name: [:id])
- (C) merge a scope from the aliased relation
merge(TheModel.some_scope)
The (A)
and (B)
part of the query will use the alias, but the (C)
will not.
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
gem "rails", github: "rails/rails"
# If you want to test against edge Rails replace the previous line with this:
# gem "rails", github: "rails/rails", branch: "main"
gem "sqlite3"
end
require "active_record"
require "minitest/autorun"
require "logger"
# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :orders, force: true do |t|
t.integer :customer_id
t.datetime :due_date
end
create_table :order_items, force: true do |t|
t.integer :order_id
end
end
class Order < ActiveRecord::Base
has_many :order_items
scope :delayed, -> { where(due_date: (Time.now..)) }
end
class OrderItem < ActiveRecord::Base
belongs_to :order
end
class BugTest < Minitest::Test
def test_association_stuff
# ok if where is added to the merged relation
OrderItem.joins(:order).merge(Order.where(customer_id: 1).delayed).take
# ok if where uses the unaliased table name and a merged scope
OrderItem.joins(:order).where(orders: { customer_id: 1 }).merge(Order.delayed).take
# ActiveRecord::StatementInvalid error if where uses the aliased name and a merged scope
OrderItem.joins(:order).where(order: { customer_id: 1 }).merge(Order.delayed).take
end
end