title: Rails/ActiveRecord: What is the correct way to establish a many to many association where one side is polymorphic?
body: <p>I have <code>Badge</code>, <code>Comment</code> and <code>Project</code>. Comments and projects can have many badges. A badge can have many comments and projects.</p>
  
  <p>Badges point to comments and projects through a join table named reactions.</p>
  
  <pre><code># reaction.rb
  class Reaction &lt; ApplicationRecord
    belongs_to :badge
    belongs_to :reaction_target, polymorphic: true
  end
  
  # badge.rb
  class Badge &lt; ApplicationRecord
    has_many :reactions
    has_many :reaction_targets, through: :reactions
  end
  
  # comment.rb
  class Comment &lt; ApplicationRecord
    has_many :reactions, as: :reaction_target
    has_many :badges, through: :reactions
  end
  
  # project.rb
  class Project &lt; ApplicationRecord
    has_many :reactions, as: :reaction_target
    has_many :badges, through: :reactions
  end
  </code></pre>
  
  <p>I can now add badges to the reaction targets:</p>
  
  <pre><code>&gt; @comment.badges &lt;&lt; Badge.first_or_create(name: "test")
  =&gt; [#&lt;Badge:0x00007fcff7619d28
    id: 1,
    name: "test",
    created_at: Sat, 23 Feb 2019 18:25:54 UTC +00:00,
    updated_at: Sat, 23 Feb 2019 18:25:54 UTC +00:00&gt;]
  </code></pre>
  
  <p>But I can't do the inverse:</p>
  
  <pre><code>&gt; Badge.first_or_create(name: "test").reaction_targets &lt;&lt; @comment
  ActiveRecord::HasManyThroughAssociationPolymorphicSourceError: Cannot have
  a has_many :through association 'Badge#reaction_targets' on the
  polymorphic object 'ReactionTarget#reaction_target' without 'source_type'.
  Try adding 'source_type: "ReactionTarget"' to 'has_many :through'
  definition. from /Users /elephant/.rvm/gems/ruby-2.6.0/gems/activerecord-5
  .2.2/lib/active_record/reflecti on.rb:932:in `check_validity!'
  </code></pre>
  
  <p>I'm not quite sure why it's suggesting I specify the source type when my associations are supposed to be polymorphic. However, I've tried:</p>
  
  <pre><code>class Badge &lt; ApplicationRecord
    has_many :reactions
    has_many :reaction_targets, through: :reactions, source_type: "ReactionTarget"
  end
  </code></pre>
  
  <p>But then I get an error:</p>
  
  <pre><code>&gt; Badge.first_or_create(name: "test").reaction_targets
  NameError: uninitialized constant Badge::ReactionTarget
  </code></pre>
  
  <p>I'm struggling to get a handle on this. What am I missing? Where have I gone wrong? What is preventing me from being able to determine the reaction targets from the badge side?</p>