Skip to content
Permalink
Browse files
Merge pull request #31895 from kamipo/do_not_attempt_to_find_inverse_…
…of_polymorphic

Make `reflection.klass` raise if `polymorphic?` not to be misused
  • Loading branch information
kamipo committed Feb 28, 2018
1 parent 7123c9b commit 63fc110
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 10 deletions.
@@ -1,3 +1,10 @@
* Make `reflection.klass` raise if `polymorphic?` not to be misused.

Fixes #31876.

*Ryuta Kamizono*


## Rails 5.2.0.rc1 (January 30, 2018) ##

* Deprecate `expand_hash_conditions_for_aggregates` without replacement.
@@ -416,6 +416,9 @@ def mapping
# Active Record class.
class AssociationReflection < MacroReflection #:nodoc:
def compute_class(name)
if polymorphic?
raise ArgumentError, "Polymorphic association does not support to compute class."
end
active_record.send(:compute_type, name)
end

@@ -608,13 +611,7 @@ def automatic_inverse_of
if can_find_inverse_of_automatically?(self)
inverse_name = ActiveSupport::Inflector.underscore(options[:as] || active_record.name.demodulize).to_sym

begin
reflection = klass._reflect_on_association(inverse_name)
rescue NameError
# Give up: we couldn't compute the klass type so we won't be able
# to find any associations either.
reflection = false
end
reflection = klass._reflect_on_association(inverse_name)

if valid_inverse_reflection?(reflection)
return inverse_name
@@ -626,9 +623,6 @@ def automatic_inverse_of
# +automatic_inverse_of+ method is a valid reflection. We must
# make sure that the reflection's active_record name matches up
# with the current reflection's klass name.
#
# Note: klass will always be valid because when there's a NameError
# from calling +klass+, +reflection+ will already be set to false.
def valid_inverse_reflection?(reflection)
reflection &&
klass <= reflection.active_record &&
@@ -732,6 +726,9 @@ def join_foreign_key
end

private
def can_find_inverse_of_automatically?(_)
!polymorphic? && super
end

def calculate_constructable(macro, options)
!polymorphic?
@@ -190,6 +190,16 @@ def test_associations_with_no_inverse_of_should_return_nil
assert_nil belongs_to_ref.inverse_of
end

def test_polymorphic_associations_dont_attempt_to_find_inverse_of
belongs_to_ref = Sponsor.reflect_on_association(:sponsor)
assert_raise(ArgumentError) { belongs_to_ref.klass }
assert_nil belongs_to_ref.inverse_of

belongs_to_ref = Face.reflect_on_association(:human)
assert_raise(ArgumentError) { belongs_to_ref.klass }
assert_nil belongs_to_ref.inverse_of
end

def test_this_inverse_stuff
firm = Firm.create!(name: "Adequate Holdings")
Project.create!(name: "Project 1", firm: firm)
@@ -2,6 +2,7 @@

class Face < ActiveRecord::Base
belongs_to :man, inverse_of: :face
belongs_to :human, polymorphic: true
belongs_to :polymorphic_man, polymorphic: true, inverse_of: :polymorphic_face
# Oracle identifier length is limited to 30 bytes or less, `polymorphic` renamed `poly`
belongs_to :poly_man_without_inverse, polymorphic: true
@@ -11,3 +11,6 @@ class Man < ActiveRecord::Base
has_many :secret_interests, class_name: "Interest", inverse_of: :secret_man
has_one :mixed_case_monkey
end

class Human < Man
end
@@ -3,6 +3,7 @@
class Sponsor < ActiveRecord::Base
belongs_to :sponsor_club, class_name: "Club", foreign_key: "club_id"
belongs_to :sponsorable, polymorphic: true
belongs_to :sponsor, polymorphic: true
belongs_to :thing, polymorphic: true, foreign_type: :sponsorable_type, foreign_key: :sponsorable_id
belongs_to :sponsorable_with_conditions, -> { where name: "Ernie" }, polymorphic: true,
foreign_type: "sponsorable_type", foreign_key: "sponsorable_id"
@@ -814,6 +814,7 @@
create_table :sponsors, force: true do |t|
t.integer :club_id
t.references :sponsorable, polymorphic: true, index: false
t.references :sponsor, polymorphic: true, index: false
end

create_table :string_key_objects, id: false, force: true do |t|
@@ -951,6 +952,7 @@
t.string :poly_man_without_inverse_type
t.integer :horrible_polymorphic_man_id
t.string :horrible_polymorphic_man_type
t.references :human, polymorphic: true, index: false
end

create_table :interests, force: true do |t|

0 comments on commit 63fc110

Please sign in to comment.