Alex Rivera | Logout

Rails Polymorphic Association with multiple associations on the same model

Asked 2010-03-22T17:41:48.427
64

My question is essentially the same as this one: Polymorphic Association with multiple associations on the same model

However, the proposed/accepted solution does not work, as illustrated by a commenter later.

I have a Photo class that is used all over my app. A post can have a single photo. However, I want to re-use the polymorphic relationship to add a secondary photo.

Before:

class Photo 
   belongs_to :attachable, :polymorphic => true
end

class Post
   has_one :photo, :as => :attachable, :dependent => :destroy
end

Desired:

class Photo 
   belongs_to :attachable, :polymorphic => true
end

class Post
   has_one :photo,           :as => :attachable, :dependent => :destroy
   has_one :secondary_photo, :as => :attachable, :dependent => :destroy
end

However, this fails as it cannot find the class "SecondaryPhoto". Based on what I could tell from that other thread, I'd want to do:

   has_one :secondary_photo, :as => :attachable, :class_name => "Photo", :dependent => :destroy

Except calling Post#secondary_photo simply returns the same photo that is attached via the Photo association, e.g. Post#photo === Post#secondary_photo. Looking at the SQL, it does WHERE type = "Photo" instead of, say, "SecondaryPhoto" as I'd like...

Thoughts? Thanks!

Edit
Report

1 Answer

3

I didn't use it, but I googled around and looked into Rails sources and I think that what you're looking for is :foreign_type. Try it and tell if it works :)

has_one :secondary_photo, :as => :attachable, :class_name => "Photo", :dependent => :destroy, :foreign_type => 'SecondaryPost'

I think that type in your question should be Post instead of Photo and, respectively, it would be better to use SecondaryPost as it assigned to Post model.

EDIT:

Above answer is completly wrong. :foreign_type is availble in polymorphic model in belongs_to association to specify name of the column that contains type of associated model.

As I look in Rails sources, this line sets this type for association:

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

As you can see it uses base_class.name to get type name. As far as I know you can do nothing with it.

So my sugestion is to add one column to Photo model, on example: photo_type. And set it to 0 if it is first photo, or set it to 1 if it is second photo. In your associations add :conditions => {:photo_type => 0} and :conditions => {:photo_type => 1}, respectively. I know it is not a solution you are looking for, but I can't find anything better. By the way, maybe it would be better to just use has_many association?

answered 2010-03-22T20:47:02.377

Your Answer