Skip to content

Commit

Permalink
Make polymorphic_inverse_of in Reflection throw an InverseOfAssociati…
Browse files Browse the repository at this point in the history
…onNotFoundError if the supplied class doesn't have the appropriate association. [#3520 state:resolved]

Signed-off-by: Eloy Duran <eloy.de.enige@gmail.com>
  • Loading branch information
h-lame authored and alloy committed Dec 28, 2009
1 parent 603b28c commit 3470b30
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 10 deletions.
4 changes: 2 additions & 2 deletions activerecord/lib/active_record/associations.rb
@@ -1,7 +1,7 @@
module ActiveRecord
class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
def initialize(reflection)
super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{reflection.class_name})")
def initialize(reflection, associated_class = nil)
super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
end
end

Expand Down
10 changes: 5 additions & 5 deletions activerecord/lib/active_record/reflection.rb
Expand Up @@ -241,16 +241,16 @@ def has_inverse?
def inverse_of
if has_inverse?
@inverse_of ||= klass.reflect_on_association(options[:inverse_of])
else
nil
end
end

def polymorphic_inverse_of(associated_class)
if has_inverse?
associated_class.reflect_on_association(options[:inverse_of])
else
nil
if inverse_relationship = associated_class.reflect_on_association(options[:inverse_of])
inverse_relationship
else
raise InverseOfAssociationNotFoundError.new(self, associated_class)
end
end
end

Expand Down
17 changes: 15 additions & 2 deletions activerecord/test/cases/associations/inverse_associations_test.rb
Expand Up @@ -523,8 +523,21 @@ def test_should_not_try_to_set_inverse_instances_when_the_inverse_is_a_has_many
assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to parent-owned instance"
end

def test_trying_to_use_inverses_that_dont_exist_should_raise_an_error
assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Face.find(:first).horrible_man }
def test_trying_to_access_inverses_that_dont_exist_shouldnt_raise_an_error
# Ideally this would, if only for symmetry's sake with other association types
assert_nothing_raised(ActiveRecord::InverseOfAssociationNotFoundError) { Face.find(:first).horrible_polymorphic_man }
end

def test_trying_to_set_polymorphic_inverses_that_dont_exist_at_all_should_raise_an_error
# fails because no class has the correct inverse_of for horrible_polymorphic_man
assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Face.find(:first).horrible_polymorphic_man = Man.first }
end

def test_trying_to_set_polymorphic_inverses_that_dont_exist_on_the_instance_being_set_should_raise_an_error
# passes because Man does have the correct inverse_of
assert_nothing_raised(ActiveRecord::InverseOfAssociationNotFoundError) { Face.find(:first).polymorphic_man = Man.first }
# fails because Interest does have the correct inverse_of
assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Face.find(:first).polymorphic_man = Interest.first }
end
end

Expand Down
3 changes: 2 additions & 1 deletion activerecord/test/models/face.rb
@@ -1,6 +1,7 @@
class Face < ActiveRecord::Base
belongs_to :man, :inverse_of => :face
belongs_to :polymorphic_man, :polymorphic => true, :inverse_of => :polymorphic_face
# This is a "broken" inverse_of for the purposes of testing
# These is a "broken" inverse_of for the purposes of testing
belongs_to :horrible_man, :class_name => 'Man', :inverse_of => :horrible_face
belongs_to :horrible_polymorphic_man, :polymorphic => true, :inverse_of => :horrible_polymorphic_face
end

0 comments on commit 3470b30

Please sign in to comment.