Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #6485 (closed defect: duplicate)

Opened 2 years ago

Last modified 1 year ago

[PATCH] Polymorphic associations + single table inheritance + *able_type doesn't record the correct object

Reported by: antonio Assigned to: David
Priority: normal Milestone: 1.2.4
Component: ActiveRecord Version: edge
Severity: normal Keywords:
Cc:

Description

Let's suppose I have some code like this:

class Picture < ActiveRecord::Base
  belongs_to :attachable, :polymorphic => true
end

class FamilyPicture < Picture
  has_one :attachment, :as => :attachable
end

class SinglePicture  < Picture
  has_one :attachment, :as => :attachable
end

Adding an Attachment to a FamilyPicture or SinglePicture (both derived from Picture) results in the addressable_type column referring to "Picture" instead of "FamilyPicture".

Firstly I had also noticed this bug on acts_as_taggable. So i decided to look over activerecord's implementation to find the bug.

Attachments

polymorphic_sti_associations_bug.diff (3.2 kB) - added by antonio on 10/24/06 23:07:14.
Patch to correct polymorphic assoc and STI
polymorphic_sti_associations_1.2.3-tested.diff (3.3 kB) - added by parasew on 05/13/07 18:34:17.
fix for polymorphic STI associations, for rails 1.2.3 (tested!)
polymorphic_sti_associations_plus_has_many_through_1.2.3.diff (5.5 kB) - added by chriseppstein on 06/13/07 07:14:01.
Cumulative patch that fixes polymorphic associations for has_many :through as well.
polymorphic_sti_associations_plus_has_many_through_edge.diff (5.5 kB) - added by wildchild on 07/24/07 01:26:18.
polymorphic_sti_associations_edge_v2.patch (11.1 kB) - added by wildchild on 07/25/07 05:59:08.
Cumulative trunk patch also fixes some calls to 'base_class.name' where 'name' expected in associations.rb
polymorphic_sti_associations_rails21.patch (7.3 kB) - added by pawulonrails on 06/19/08 21:33:57.
Polymorphic_sti_associations_edge_v2.patch adjusted for Rails 2.1. I'm not Rails expert, so this patch may break things. But in my simple tests it worked.

Change History

10/24/06 23:07:14 changed by antonio

  • attachment polymorphic_sti_associations_bug.diff added.

Patch to correct polymorphic assoc and STI

(in reply to: ↑ description ) 10/24/06 23:12:54 changed by antonio

I've been running it in a 'real world' application here and on acts_as_taggable. Both ork well. I've also made some tests cases. THe problem is: it doesn't go forward with default active record's test cases. I wasn't able to make the proper corrections to the tests cases. But i'm sure this patch is OK (at least logically)

I can append my tests cases in any case.

12/27/06 19:12:34 changed by otavio

I was also having troubles with Polymorphic handling and this patch solved it. Now Rails discover the right class and work as desired.

12/27/06 19:13:34 changed by otavio

  • version changed from edge to 1.1.6.

(follow-up: ↓ 5 ) 12/27/06 19:14:17 changed by otavio

I'm able to reproduce the problens and apply it on 1.1.6. I hadn't check if 1.2 has the same problem.

(in reply to: ↑ 4 ) 03/27/07 20:37:19 changed by gumayunov

  • version changed from 1.1.6 to 1.2.3.

Replying to otavio:

I'm able to reproduce the problens and apply it on 1.1.6. I hadn't check if 1.2 has the same problem.

yes 1.2.3 has one

05/10/07 06:25:34 changed by basic

The patch seems to work in 1.2.3 as well, even though the line numbers are off quite a bit.

05/13/07 18:34:17 changed by parasew

  • attachment polymorphic_sti_associations_1.2.3-tested.diff added.

fix for polymorphic STI associations, for rails 1.2.3 (tested!)

05/13/07 18:34:37 changed by parasew

the old patch seems to not patch all the files in rails 1.2.3. attached is a diff that works with rails 1.2.3. i tested it, works like a charm. this should really be put into rails-core since lots of people are using STI and might use polymorphic associations as well, wondering why things start to go wrong.

05/15/07 14:46:44 changed by basic

It still doesn't work when using has_many with :as => 'something' and :dependent => :delete_all (or :destroy) in the base class.

The problem is in rails/activerecord/lib/active_record/associations.rb, function configure_dependency_for_has_many(), line 1049:

dependent_conditions += " AND #{reflection.options[:as]}_type = '#{base_class.name}'"

Here the type field is forced to the base class of the object, which is wrong.

As a workaround, having this in the base class works:

has_many :permissions, :as => 'authobject' def destroy

self.permissions.each {|p| p.destroy} super

end

Is it possible to get Rails to not hard code the condition string immediately, but create it for the correct object, just as when following the relationship? Since "self.permissions" work (with the above patch), it's on the right track. I tried to fix it myself, but couldn't find the right class name.

06/13/07 07:12:47 changed by chriseppstein

The tested patch fails for has_many :through associations. Here's a cumulative patch containing my fix to has_many :through as well.

06/13/07 07:14:01 changed by chriseppstein

  • attachment polymorphic_sti_associations_plus_has_many_through_1.2.3.diff added.

Cumulative patch that fixes polymorphic associations for has_many :through as well.

07/24/07 00:54:38 changed by wildchild

  • priority changed from normal to high.
  • severity changed from normal to major.

chriseppstein, your patch won't work with trunk, because there is no method 'quote':

from changelog * Rename AR::Base#quote so people can use that name in their models. #3628 [Koz]

07/24/07 01:26:18 changed by wildchild

  • attachment polymorphic_sti_associations_plus_has_many_through_edge.diff added.

07/25/07 02:07:38 changed by wildchild

  • version changed from 1.2.3 to edge.
  • milestone changed from 1.x to 1.2.4.

07/25/07 05:59:08 changed by wildchild

  • attachment polymorphic_sti_associations_edge_v2.patch added.

Cumulative trunk patch also fixes some calls to 'base_class.name' where 'name' expected in associations.rb

08/28/07 14:10:18 changed by olly

+1

(in reply to: ↑ description ; follow-up: ↓ 14 ) 08/28/07 20:51:51 changed by bitsweat

  • status changed from new to closed.
  • resolution set to invalid.

Replying to antonio:

Let's suppose I have some code like this: {{{ class Picture < ActiveRecord::Base belongs_to :attachable, :polymorphic => true end class FamilyPicture < Picture has_one :attachment, :as => :attachable end class SinglePicture < Picture has_one :attachment, :as => :attachable end }}} Adding an Attachment to a FamilyPicture or SinglePicture (both derived from Picture) results in the addressable_type column referring to "Picture" instead of "FamilyPicture".

This is an implementation detail, not a bug.

When the addressable is instantiated, you'll get a FamilyPicture or SinglePicture based on the pictures.type column (NOT the pictures.addressable_type column).

Also, the patch lacks tests demonstrating what is meant to be fixed.

(in reply to: ↑ 13 ) 09/05/07 16:54:32 changed by robert.head

This is an implementation detail, not a bug. When the addressable is instantiated, you'll get a FamilyPicture or SinglePicture based on the pictures.type column (NOT the pictures.addressable_type column).

How does it help to simply declare the bug invalid?

I'll look into my code to see if I'm missing something, but I wasn't able to get polymorphic associations to work with STI at all until applying the patches.

09/05/07 16:58:26 changed by olly

I also don't agree that this is a implementation detail. We had working code on 1.2, then upgraded to edge, and this patch fixed the tests. It might be lacking some polish, but it defiantly works.

09/05/07 17:04:42 changed by basic

I also still consider this a bug. We have a very similar situation with polymorphic associations where one of the alternatives uses inheritance, and that doesn't work at all without these patches. Not because the wrong class name is stored in one of the tables, but because the wrong type is instanciated when following the relationship. The patch and test might not be perfect, but it's still an unresolved bug.

09/05/07 17:33:23 changed by robert.head

  • status changed from closed to reopened.
  • resolution deleted.

In response to the multiple voices here, I'm reopening the ticket.

09/05/07 20:30:58 changed by lifofifo

  • priority changed from high to normal.
  • severity changed from major to normal.

09/28/07 16:27:27 changed by bitsweat

  • keywords set to rails2.

09/28/07 16:34:16 changed by bitsweat

  • keywords deleted.
  • status changed from reopened to closed.
  • resolution set to duplicate.

06/19/08 21:33:57 changed by pawulonrails

  • attachment polymorphic_sti_associations_rails21.patch added.

Polymorphic_sti_associations_edge_v2.patch adjusted for Rails 2.1. I'm not Rails expert, so this patch may break things. But in my simple tests it worked.