Can join tables be polymorphic?

For example:
Currently I have:
functions < functions_competencies < competencies
exams < exam_competencies < competencies

I'd like to dry up "functions_competencies" and "exam_competencies" by
using a polymorphic association, by let's say 'attached_competencies':

functions < attached_competencies < competencies
exams < attached_competencies < competencies
evaluations < attached_competencies < competencies
...

Note that these are join tables.

Is this possible?

This is only somewhat possible - you can do a has_many :through from
the specific classes to the general, but the other direction will get
you an exception. In your case:

in function.rb:

has_many :attached_competencies, :as => :competency_thing, :dependent
=> :destroy
has_many :competencies, :through => :attached_competencies # this
works

in attached_competency.rb:

belongs_to :competency_thing, :polymorphic => true
belongs_to :competency

in competency.rb:

has_many :attached_competencies, :dependent => :destroy
has_many :???, :through => :attached_competencies # THIS WILL NOT WORK

You *can* do a through for a particular type (in competency.rb again):

has_many :functions, :through => :attached_competencies, :source
=> :competency_thing, :source_type => 'Function'

Which may or may not be sufficient for your purposes.

--Matt Jones

Andy Tolle wrote in post #991031:

For example:
Currently I have:
functions < functions_competencies < competencies
exams < exam_competencies < competencies

I'd like to dry up "functions_competencies" and "exam_competencies" by
using a polymorphic association, by let's say 'attached_competencies':

functions < attached_competencies < competencies
exams < attached_competencies < competencies
evaluations < attached_competencies < competencies
...

Note that these are join tables.

Is this possible?

IIRC, this is based on the has_many_polymorphs plugin

class appl
  has_many :appllinks
  has_many :projects,
           :through => :appllinks,
           :source => :project,
           :conditions =>? "appllinks.appllinkable_type = 'Project'"
  has_many :scenarios,
           :through => :appllinks,
           :source => :scenario,
           :conditions =>? "appllinks.appllinkable_type = 'Scenario'"
  has_many :unittests,
           :through => :appllinks,
           :source => :unittest,
           :conditions =>? "appllinks.appllinkable_type = 'Unittest'"

class appllink
  belongs_to :appl
  belongs_to :appllinkable, :polymorphic => true
  belongs_to :project,
             :class_name => 'Project',
             :foreign_key => 'appllinkable_id'
  belongs_to :scenario,
             :class_name => 'Scenario',
             :foreign_key => 'appllinkable_id'
  belongs_to :unittest,
             :class_name => 'Unittest',
             :foreign_key => 'appllinkable_id'

class project
  has_many :appllinks, :as => :applinkable, :dependent => :destroy
  has_many :appls, :through => :appllinks

classes scenario and unittest are just like project

YMMV