Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Add inverse polymorphic association support

#3520

The attached patch adds support for :inverse_of on a polymorphic belongs_to association.

require 'active_record'
ActiveRecord::Base.establish_connection('adapter' => "sqlite3", 'database' => ":memory:")
ActiveRecord::Schema.define do
  create_table :parents do
  end
  create_table :children do |t|
    t.integer :parent_id
    t.string :parent_type
  end
end

class Parent < ActiveRecord::Base
  has_one :child, :as => :parent, :inverse_of => :parent
end

class Child < ActiveRecord::Base
  belongs_to :parent, :polymorphic => true, :inverse_of => :child
end

parent = Parent.new(:child => Child.new)
parent.child.parent.target.equal?(parent)  # true

Reported by George Ogata · November 29th, 2009 @ 08:43 PM

State: resolved
Milestone: 2.3.6
Assigned to: Michael Koziarski Michael Koziarski
Importance: none

Activity

  1. Eloy Duran
    Eloy Duran
    • Assigned user set to Michael Koziarski

    I’m wondering, why do you need to fix all these other tests? Eg:

    -    m = Man.find(:first, :include => :interests)
    +    m = Man.find(:first, :conditions => {:name => 'Gordon'}, :include => :interests)
    

    Is it simply because you want to use a specific fixture? Or does the patch somehow change existing functionality elsewhere?

    December 17th, 2009 @ 11:01 AM

  2. Eloy Duran
  3. Eloy Duran
    Eloy Duran
    • State changed from new to verified

    Oh, and it applies and runs :)

    December 17th, 2009 @ 11:15 AM

  4. Murray Steele
    Murray Steele

    George's above patch is good. However, attached is a new patch that:

    a) includes George's patch tweaked to apply cleanly on top of my extra tests patch for #3513
    b) adds another test for checking that polymorphic belongs_to associations can be assigned via direct accessor not just the .replace method
    c) provides a slightly more robust we_can_set_the_inverse_on_this? method for polymorphic belongs_to associations.

    December 17th, 2009 @ 12:27 PM

  5. Murray Steele
    Murray Steele

    One concern I have is that a polymorphic belongs_to using :inverse_of will never throw an InverseOfAssociationNotFoundError if the supplied :inverse_of doesn't actually match. This breaks symmetry with the other :inverse_of associations, but I'm not sure exactly what the correct place to throw such an error might be. We can't throw it during class definition, as the :inverse_of depends on the class of the polymorphic instance, but throwing it during assignment (or load) seems a tad late in the process.

    Note, I don't think this should hold up this patch though.

    December 17th, 2009 @ 12:31 PM

  6. Murray Steele
    Murray Steele

    In response to Eloy's comments on IRC, the attached patch now makes polymorphic_inverse_of on Reflection throw an InverseOfAssociationNotFoundError if the supplied associated_class doesn't have the correct association on it.

    There are 2 tests for this that appear to test the same thing, but I think they are subtly different:

    1. test that it throws if the association is broken (e.g. nothing has the correct inverse - it would throw regardless of what we try to assign)
    2. test that it throws if the association is fine, but the instance being assigned doesn't have the correct association (e.g. we can assign some things, but not others)

    December 17th, 2009 @ 04:15 PM

  7. Eloy Duran
    Eloy Duran

    @Murray: I applied your last patch to 2-3-stable. I hope you don't mind I removed a few lines of code. Namely, returning ‘nil’ from an ‘else’ clause isn't necessary.

    December 28th, 2009 @ 01:12 PM

  8. Repository
    Repository
    • State changed from verified to resolved

    (from [cca75ca23f7c2a144104e1d96378e7afd9fdd189]) Add inverse polymorphic association support. [#3520 state:resolved]

    Signed-off-by: Eloy Duran eloy.de.enige@gmail.com
    http://github.com/rails/rails/commit/cca75ca23f7c2a144104e1d96378e7...

    December 28th, 2009 @ 08:29 PM

  9. Repository
    Repository

    (from [603b28c84c1ba1d013247fee450d82f015aaefb3]) Provide a slightly more robust we_can_set_the_inverse_on_this? method for polymorphic belongs_to associations. [#3520 state:resolved]

    Also add a new test for polymorphic belongs_to that test direct accessor assignment, not just .replace assignment.

    Signed-off-by: Eloy Duran eloy.de.enige@gmail.com
    http://github.com/rails/rails/commit/603b28c84c1ba1d013247fee450d82...

    December 28th, 2009 @ 08:29 PM

  10. Repository
    Repository

    (from [3470b306bb22df0394025f4dcf3915eb1166ac23]) Make polymorphic_inverse_of in Reflection throw an InverseOfAssociationNotFoundError if the supplied class doesn't have the appropriate association. [#3520 state:resolved]

    Signed-off-by: Eloy Duran eloy.de.enige@gmail.com
    http://github.com/rails/rails/commit/3470b306bb22df0394025f4dcf3915...

    December 28th, 2009 @ 08:29 PM

  11. Repository
  12. Repository
    Repository

    (from [6a74ee7f4deea4a44520d3fcc9120e0bb848823f]) Provide a slightly more robust we_can_set_the_inverse_on_this? method for polymorphic belongs_to associations. [#3520 state:resolved]

    Also add a new test for polymorphic belongs_to that test direct accessor assignment, not just .replace assignment.

    Signed-off-by: Eloy Duran eloy.de.enige@gmail.com
    http://github.com/rails/rails/commit/6a74ee7f4deea4a44520d3fcc9120e...

    December 28th, 2009 @ 08:52 PM

  13. Repository
    Repository

    (from [ff508640e28914da2b546f6a8c9f215bab201b61]) Make polymorphic_inverse_of in Reflection throw an InverseOfAssociationNotFoundError if the supplied class doesn't have the appropriate association. [#3520 state:resolved]

    Signed-off-by: Eloy Duran eloy.de.enige@gmail.com
    http://github.com/rails/rails/commit/ff508640e28914da2b546f6a8c9f21...

    December 28th, 2009 @ 08:52 PM