[Boulder Ruby Group] has_many / polymorphic

ara howard ara.t.howard at gmail.com
Sun May 25 01:42:48 EDT 2008


hi all -

i've got roughly the following from a legacy db (so no suggestions of  
changing schema)


a class which models a peice a web content

   class WebContent
     # web_contentid | content
   end

a join table which maps to various associated things, here type is  
almost
exactly the same as is used for rails sti/polymorphic associations.   
details
is the foreign key pointing to that type.

   class WebContentAssociation
     # web_contentid | type | details
   end

also there are various models, of course, which can be related to a  
peice of
web content.

   class Country
     # countrycode | ...
   end

   class School
     # schoolcode | ...
   end


so a sample WebContentAssociation row might be

   42 | 'country' | 'usa'

aka web content # 42 is associated with country 'usa'


the issue i'm having is this: it seems like a good case for polymorphic
associations and, in the case of belongs to associations this is true,  
but for
has_many associations i can't quite figure out if i'm missing  
something, or if
rails is missing something to make the 'right thing' happen with these
relationships.  so for example, i'd like to be able to say

   web_content.countries

but the issue, i think, is not being able to specify the type/ 
foreign_key
columns for has_many associations in the same way that you can for  
polymorphic
belongs to associations.


so while i *can* do something like this

   class WebContent
     has_many :web_content_associations, :foreign_key => "web_contentid"
     has_many :countries, :through => :web_content_associations
   end

   class WebContentAssociation
     belongs_to :web_content, :foreign_key => "web_contentid"
     belongs_to :country, :foreign_key => "details", :conditions =>  
"type='country'"
   end

   class Country
     has_many :web_content_associations, :foreign_key =>  
"details", :conditions => "type='country'", :dependent => :destroy
     has_many :web_contents, :through => :web_content_associations
   end

   p web_content.countries

i cannnot do something like

   class WebContent
     has_many :web_content_associations, :foreign_key => "web_contentid"
     has_many :associations, :through => :web_content_associations
   end

   class WebContentAssociation
     belongs_to :web_content, :foreign_key => "web_contentid"
     belongs_to :association, :polymorphic => true, :foreign_type =>  
"type", :foreign_key => "details"
   end

   class Country
     has_many :web_content_associations, :as => :association       ###  
of course this breaks down...
     has_many :web_contents, :through => :web_content_associations
   end

   p web_content.countries


as far as i can tell this is because

   has_many :web_content_associations, :as => :associations

pins the sql to

   'where association_id=xx and association_type=yy'

instead of the

   'where details=xx and type=yy'

which is what i need.


in otherwords i need to configure

   has_many :foos, :as => :bars

to *not* use

   'bars_type' and 'bars_id'

but two other fields.


anyone know if this is possible?


cheers


note : the application is using the composite primary key plugin, so
Model.find(id) is a bit perverted from the 'normal' ar way...



a @ http://codeforpeople.com/
--
we can deny everything, except that we have the possibility of being  
better. simply reflect on that.
h.h. the 14th dalai lama





More information about the Bdrg-members mailing list