Skip to content

Commit

Permalink
Fixes polymorphic joins.
Browse files Browse the repository at this point in the history
* Polymorphic joins have been missing a critical join constraint that
is responsible for only returning polymorphic records of the specified
type.

* Override ActiveRecord::Reflection::AbstractReflection#join_scope to
add this constraint if the reflection is polymorphic.
  • Loading branch information
PhilCoggins committed May 11, 2020
1 parent 90dd40d commit 01d35ef
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 6 deletions.
21 changes: 15 additions & 6 deletions lib/polyamorous/activerecord_5.2_ruby_2/reflection.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
module Polyamorous
module ReflectionExtensions
def build_join_constraint(table, foreign_table)
if polymorphic?
super(table, foreign_table)
.and(foreign_table[foreign_type].eq(klass.name))
else
super(table, foreign_table)
if ActiveRecord.version > ::Gem::Version.new('5.2.3')
def join_scope(table, foreign_table, foreign_klass)
if respond_to?(:polymorphic?) && polymorphic?
super.where!(foreign_table[foreign_type].eq(klass.name))
else
super
end
end
else
def build_join_constraint(table, foreign_table)
if polymorphic?
super.and(foreign_table[foreign_type].eq(klass.name))
else
super
end
end
end
end
Expand Down
4 changes: 4 additions & 0 deletions spec/ransack/search_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ module Ransack
let(:children_people_name_field) {
"#{quote_table_name("children_people")}.#{quote_column_name("name")}"
}
let(:notable_type_field) {
"#{quote_table_name("notes")}.#{quote_column_name("notable_type")}"
}
it 'evaluates conditions contextually' do
s = Search.new(Person, children_name_eq: 'Ernie')
expect(s.result).to be_an ActiveRecord::Relation
Expand Down Expand Up @@ -328,6 +331,7 @@ module Ransack
s = Search.new(Note, notable_of_Person_type_name_eq: 'Ernie').result
expect(s).to be_an ActiveRecord::Relation
expect(s.to_sql).to match /#{people_name_field} = 'Ernie'/
expect(s.to_sql).to match /#{notable_type_field} = 'Person'/
end

it 'evaluates nested conditions' do
Expand Down

0 comments on commit 01d35ef

Please sign in to comment.