From 578256021147f14d96b15d0fb2c063a14f3a4756 Mon Sep 17 00:00:00 2001 From: Sean Collins Date: Tue, 2 Jul 2024 17:27:22 -0600 Subject: [PATCH 1/2] Support table aliases on associated relations --- lib/rom/sql/relation/reading.rb | 2 ++ spec/unit/relation/inner_join_spec.rb | 28 ++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/rom/sql/relation/reading.rb b/lib/rom/sql/relation/reading.rb index 0cadf192e..d5afa9e48 100644 --- a/lib/rom/sql/relation/reading.rb +++ b/lib/rom/sql/relation/reading.rb @@ -1107,6 +1107,8 @@ def __join__(type, other, join_cond = EMPTY_HASH, opts = EMPTY_HASH, &block) end new(dataset.__send__(type, other.name.dataset.to_sym, join_cond, join_opts)) + elsif opts[:table_alias] + new(dataset.__send__( type, other.name.key, join_cond, opts)) else associations[other.name.key].join(type, self, other) end diff --git a/spec/unit/relation/inner_join_spec.rb b/spec/unit/relation/inner_join_spec.rb index 62c99e0bc..fb7a52179 100644 --- a/spec/unit/relation/inner_join_spec.rb +++ b/spec/unit/relation/inner_join_spec.rb @@ -38,7 +38,7 @@ ]) end - it 'allows specifying table_aliases' do + it 'allows specifying table_alias with table name' do relation.insert id: 3, name: 'Jade' result = relation @@ -193,6 +193,32 @@ def name expect(result.to_a).to eql([name: 'Jane', text: 'solved by Jane']) end + + it 'allows specifying table_alias with association name' do + result = relation + .inner_join(:tasks, { user_id: :id }, table_alias: :t1) + .select(:name, tasks[:title].qualified(:t1)) + + expect(result.schema.map(&:name)).to eql(%i[name title]) + + expect(result.to_a).to eql([ + { name: 'Jane', title: "Jane's task" }, + { name: 'Joe', title: "Joe's task" } + ]) + end + + it 'allows specifying table_alias with relation' do + result = relation + .inner_join(tasks, { user_id: :id }, table_alias: :requirements) + .select(:name, tasks[:title].qualified(:requirements)) + + expect(result.schema.map(&:name)).to eql(%i[name title]) + + expect(result.to_a).to eql([ + { name: 'Jane', title: "Jane's task" }, + { name: 'Joe', title: "Joe's task" } + ]) + end end end end From 339e234b044e37317acc6c3eb7acc25b835df80f Mon Sep 17 00:00:00 2001 From: Sean Collins Date: Tue, 2 Jul 2024 18:24:33 -0600 Subject: [PATCH 2/2] Support table aliases on aliased associations --- lib/rom/sql/relation/reading.rb | 9 ++++++--- spec/unit/relation/inner_join_spec.rb | 13 +++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/rom/sql/relation/reading.rb b/lib/rom/sql/relation/reading.rb index d5afa9e48..c92091664 100644 --- a/lib/rom/sql/relation/reading.rb +++ b/lib/rom/sql/relation/reading.rb @@ -1086,13 +1086,16 @@ def coerce_conditions(conditions) # @api private def __join__(type, other, join_cond = EMPTY_HASH, opts = EMPTY_HASH, &block) if other.is_a?(Symbol) || other.is_a?(ROM::Relation::Name) - if join_cond.equal?(EMPTY_HASH) && !block - assoc = associations[other] + assoc = associations.key?(other) && associations[other] + + if join_cond.eql?(EMPTY_HASH) && !block assoc.join(type, self) elsif block __join__(type, other, JoinDSL.new(schema).(&block), opts) + elsif assoc + new(dataset.__send__(type, assoc.target.name.to_sym, join_cond, opts, &block)) else - new(dataset.__send__(type, other.to_sym, join_cond, opts, &block)) + new(dataset.__send__(type, other, join_cond, opts, &block)) end elsif other.is_a?(Sequel::SQL::AliasedExpression) new(dataset.__send__(type, other, join_cond, opts, &block)) diff --git a/spec/unit/relation/inner_join_spec.rb b/spec/unit/relation/inner_join_spec.rb index fb7a52179..a8c5740ae 100644 --- a/spec/unit/relation/inner_join_spec.rb +++ b/spec/unit/relation/inner_join_spec.rb @@ -219,6 +219,19 @@ def name { name: 'Joe', title: "Joe's task" } ]) end + + it 'allows specifying table_alias with association name different from relation name' do + result = relation + .inner_join(:todos, {user_id: :id}, table_alias: :requirements) + .select(:name, tasks[:title].qualified(:requirements)) + + expect(result.schema.map(&:name)).to eql(%i[name title]) + + expect(result.to_a).to eql([ + { name: 'Jane', title: "Jane's task" }, + { name: 'Joe', title: "Joe's task" } + ]) + end end end end