ruby-on-railspolymorphic-associations

How to write a Rails polymorphic association query with a join table


I have a many to many relationship through a polymorphic association and I'm having trouble writing my query

Here's my migration:

  def change
    create_table :excuses do |t|
      t.string :label
      t.integer :status, default: 0, null: false

      t.timestamps
    end

    create_table :excuses_excusables do |t|
      t.references :excusable, polymorphic: true, index: true, null: false
      t.integer :excuse_id, index: true, null: false
    end
  end

The idea is that I can associate an Excuse to one of my existing tables, re_evalutations such that from the re_evaluation I can call re_evaluation.excuse. Excuses are pre-defined set of excuses that a User will choose from which is why I went the many-to-many route.

The part that I cannot figure out is how to call excuse.re_evaluations to be able to fetch all re_evaluations with a given excuse.

class ReEvaluation < ApplicationRecord
  has_one :excuses_excusable, as: :excusable
  has_one :excuse, through: :excuses_excusable
end

class Excuse < ApplicationRecord
    has_many :excuses_excusables, foreign_key: :excuse_id
    
    # Does not work
    # has_many :re_evaluations, through: :excuses_excusables, source_type: "ReEvaluation"
end

class ExcusesExcusable < ApplicationRecord
    belongs_to :excusable, polymorphic: true
    belongs_to :excuse
end

How can I modify these associations to allow me to call excuse.re_evaluations?


Solution

  • You correctly used the source_type attribute to specify correct type filter on your polymorphic association. However the source association (excusable) cannot be inferred from the associotion name (re_evaluations) and you need to specify it explicitly (source: :excusable).

    Therefore if you modify your code like this, it should work:

    has_many :re_evaluations, through: :excuses_excusables, source: :excusable, source_type: "ReEvaluation"