Skip to content

Commit 169502b

Browse files
oneirosscarroll32
andauthored
Fix wrong table aliases in Rails 6.1 (#1447)
This simply mirrors ActiveRecord's "deduplication" of joined tables, to not use table aliases that are not actually in the final query's JOIN clause. Co-authored-by: Sean <sean@immersive.ch>
1 parent edbe544 commit 169502b

File tree

3 files changed

+58
-4
lines changed

3 files changed

+58
-4
lines changed

lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,21 @@ def construct_tables_for_association!(join_root, association)
5656
private
5757

5858
def table_aliases_for(parent, node)
59+
@joined_tables ||= {}
5960
node.reflection.chain.map { |reflection|
60-
alias_tracker.aliased_table_for(reflection.klass.arel_table) do
61-
root = reflection == node.reflection
62-
name = reflection.alias_candidate(parent.table_name)
63-
root ? name : "#{name}_join"
61+
table, terminated = @joined_tables[reflection]
62+
root = reflection == node.reflection
63+
64+
if table && (!root || !terminated)
65+
@joined_tables[reflection] = [table, true] if root
66+
table
67+
else
68+
table = alias_tracker.aliased_table_for(reflection.klass.arel_table) do
69+
name = reflection.alias_candidate(parent.table_name)
70+
root ? name : "#{name}_join"
71+
end
72+
@joined_tables[reflection] ||= [table, root] if join_type == Arel::Nodes::OuterJoin
73+
table
6474
end
6575
}
6676
end

spec/ransack/adapters/active_record/base_spec.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,22 @@ module ActiveRecord
141141
end
142142
end
143143

144+
context 'has_one through associations' do
145+
let(:address) { Address.create!(city: 'Boston') }
146+
let(:org) { Organization.create!(name: 'Testorg', address: address) }
147+
let!(:employee) { Employee.create!(name: 'Ernie', organization: org) }
148+
149+
it 'works when has_one through association is first' do
150+
s = Employee.ransack(address_city_eq: 'Boston', organization_name_eq: 'Testorg')
151+
expect(s.result.to_a).to include(employee)
152+
end
153+
154+
it 'works when has_one through association is last' do
155+
s = Employee.ransack(organization_name_eq: 'Testorg', address_city_eq: 'Boston')
156+
expect(s.result.to_a).to include(employee)
157+
end
158+
end
159+
144160
context 'negative conditions on HABTM associations' do
145161
let(:medieval) { Tag.create!(name: 'Medieval') }
146162
let(:fantasy) { Tag.create!(name: 'Fantasy') }

spec/support/schema.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,20 @@ class Account < ApplicationRecord
237237
belongs_to :trade_account, class_name: "Account"
238238
end
239239

240+
class Address < ApplicationRecord
241+
has_one :organization
242+
end
243+
244+
class Organization < ApplicationRecord
245+
belongs_to :address
246+
has_many :employees
247+
end
248+
249+
class Employee < ApplicationRecord
250+
belongs_to :organization
251+
has_one :address, through: :organization
252+
end
253+
240254
module Schema
241255
def self.create
242256
ActiveRecord::Migration.verbose = false
@@ -300,6 +314,20 @@ def self.create
300314
t.belongs_to :agent_account
301315
t.belongs_to :trade_account
302316
end
317+
318+
create_table :addresses, force: true do |t|
319+
t.string :city
320+
end
321+
322+
create_table :organizations, force: true do |t|
323+
t.string :name
324+
t.integer :address_id
325+
end
326+
327+
create_table :employees, force: true do |t|
328+
t.string :name
329+
t.integer :organization_id
330+
end
303331
end
304332

305333
10.times do

0 commit comments

Comments
 (0)