Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails inverse of Polymorphic association in concern gives TypeError: can't cast Class

I am trying to use the information in this tutorial to learn concerns with polymorphic associations. I have the following:

concerns/taggable.rb:

module Taggable
  extend ActiveSupport::Concern

  included do
    has_many :taggings, :as => :taggable
    has_many :tags, :through => :taggings
  end

  def tag_list
    tags.map(&:name).join(', ')
  end

  def tag_list=(names)
    self.tags = names.split(',').map do |name|
      Tag.where(name: name.strip).first_or_create!
    end
  end

  module ClassMethods
    def tag_counts
      Tag.select('tags.*, count(taggings.tag_id) as count').joins(:taggings).group('taggings.tag_id')
    end
  end
end

models/article.rb:

class Article < ApplicationRecord
  include Taggable

  def self.tagged_with(name)
    Tag.find_by!(name: name).articles
  end

end

models/tagging.rb:

class Tagging < ApplicationRecord

  belongs_to :tag
  belongs_to :taggable, :polymorphic => true

end

models/tag.rb:

class Tag < ApplicationRecord
  has_many :taggings
  has_many :articles, through: :taggings, source: :taggable, source_type: Article

end

The forward associations work just fine. I can ask:

Article.first.tags
#=> Article Load (0.2ms)  SELECT  "articles".* FROM "articles" ORDER BY "articles"."id" ASC LIMIT ?  [["LIMIT", 1]]
Tag Load (0.3ms)  SELECT  "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = ? AND "taggings"."taggable_type" = ? LIMIT ?  [["taggable_id", 1], ["taggable_type", "Article"], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Tag id: 1, name: "Superhero", created_at: "2017-11-12 21:06:33", updated_at: "2017-11-12 21:06:33">, #<Tag id: 2, name: "Bat", created_at: "2017-11-12 21:06:33"...

But if I do:

Tag.first.articles
Tag Load (0.3ms)  SELECT  "tags".* FROM "tags" ORDER BY "tags"."id" ASC LIMIT ?  [["LIMIT", 1]]
TypeError: can't cast Class

I've tried several variations on the associations in the tag.rb model but can't seem to find any that works.

like image 435
Beartech Avatar asked Oct 28 '25 03:10

Beartech


1 Answers

The source_type in the Tag's has_many :through association needs to be a string:

has_many :articles, through: :taggings, source: :taggable, source_type: "Article"
like image 70
rramos Avatar answered Oct 30 '25 05:10

rramos



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!