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

Ticket #8638 (closed defect: fixed)

Opened 2 years ago

Last modified 2 years ago

[PATCH]creating associations on an abstract class

Reported by: daxhuiberts Assigned to: lifofifo
Priority: normal Milestone: 1.2.4
Component: ActiveRecord Version: edge
Severity: normal Keywords: has_one polymorphic abstract
Cc: lifofifo

Description

Hi,

I have the following setup:

class Item < ActiveRecord::Base
  belongs_to :item, :polymorphic => true
end

class AbstractItem < ActiveRecord::Base
  has_one :item, :as => :item
  def self.abstract_class?; self == AbstractItem; end
end

class Post < AbstractItem
end

Now, when I do a post = Post.find :first, :include => :item inside my controller, post.item will be nil. I can do post = Post.find :first and then post.item will work, but it uses a second query.

But if I don't use AbstractItem and use Post as follow:

class Post < ActiveRecord::Base
  has_one :item, :as => :item
end

Then post = Post.find :first, :include => :item will work just fine, takes one query, nada problems.

The reason I would like an abstract model is because there will be a lot of identical functionality within all the item types.

Aparently you can't do a has_one (or has_many) on an abstract class, it will not work.

Attachments

fix_eager_loading.diff (4.8 kB) - added by lifofifo on 06/25/07 20:43:45.
Fix the problem and test cases for the same

Change History

06/13/07 00:52:03 changed by bitsweat

  • keywords set to has_one polymorphic abstract.

What SQL do you see for the failing case?

06/16/07 13:51:07 changed by daxhuiberts

The correct one where the association is in Post (see: items.item_type = 'Post'):

SELECT posts.`id` AS t0_r0, posts.`title` AS t0_r1,
  posts.`body` AS t0_r2, items.`id` AS t1_r0,
  items.`item_id` AS t1_r1, items.`item_type` AS t1_r2,
  items.`created_at` AS t1_r3
FROM posts LEFT OUTER JOIN items
  ON items.item_id = posts.id AND items.item_type = 'Post'
ORDER BY items.created_at DESC

And the incorrect one where the association is in AbstractItem (see: items.item_type = 'AbstractItem'):

SELECT posts.`id` AS t0_r0, posts.`title` AS t0_r1,
  posts.`body` AS t0_r2, items.`id` AS t1_r0,
  items.`item_id` AS t1_r1, items.`item_type` AS t1_r2,
  items.`created_at` AS t1_r3
FROM posts LEFT OUTER JOIN items
  ON items.item_id = posts.id AND items.item_type = 'AbstractItem'
ORDER BY items.created_at DESC

Apparently polymorphic associations don't check on the 'abstract_class?' value.

06/25/07 00:51:28 changed by lifofifo

  • cc set to lifofifo.

06/25/07 02:11:35 changed by lifofifo

  • summary changed from creating associations on an abstract class to [PATCH]creating associations on an abstract class.

I've attached a patch to correct eager loading query for has_many/has_one polymorhic associations defined in abstract parent class are used by subclasses.

06/25/07 10:12:25 changed by lifofifo

  • owner changed from core to lifofifo.
  • status changed from new to assigned.

06/25/07 10:32:10 changed by lifofifo

Actually this is a very simple patch. JoinAssociation should have same logic for has_many and has_one polymorphs. The patch also removes a block of duplicate code and fixes this issue.

Thanks.

06/25/07 18:19:47 changed by bitsweat

  • status changed from assigned to closed.
  • resolution set to untested.

Please add a test verifying the fix (test should fail before the patch but succeed after).

06/25/07 20:43:45 changed by lifofifo

  • attachment fix_eager_loading.diff added.

Fix the problem and test cases for the same

06/25/07 20:44:51 changed by lifofifo

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

06/25/07 20:45:23 changed by lifofifo

I've added a verifying test case.

Thanks.

06/25/07 22:42:23 changed by bitsweat

  • status changed from reopened to closed.
  • resolution set to fixed.

(In [7119]) Fix polymorphic has_one associations declared in an abstract class. Closes #8638.