Polymorphic has_many :through NoMethodError: undefined method 'klass' for nil:NilClass



所以我开始在我的应用程序中设置一个has_many:through多态关联。模型如下所示:

class Song < ActiveRecord::Base
  has_many :collections, through: :collectionitems
  has_many :collectionitems, through: :collectable
end
class Album < ActiveRecord::Base
  has_many :collections, through: :collectionitems
  has_many :collectionitems, through: :collectable
end
class Collection < ActiveRecord::Base
  has_many :albums, through: :collectionitems, source: :collectable, source_type: "Album"
  has_many :songs, through: :collectionitems, source: :collectable, source_type: "Song"
  has_many :collectionitems
end
class Collectionitem < ActiveRecord::Base
  belongs_to :collection
  belongs_to :collectable, polymorphic: true
end

这允许我执行以下调用:

Collection.first.songs => 返回第一个集合的歌曲数组 Collection.first.albums => 返回第一个集合的专辑数组 Collectionitem.first.collection => 返回此集合项所属的集合 Collectionitem.first.collectable => 返回此收藏项所属的记录(歌曲或专辑(

当我尝试查找特定专辑或歌曲所属的所有收藏集时,我的问题就来了。

在 Rails 控制台中调用时,Song.first.collectionsAlbum.first.collections 都会返回以下错误。

Song.first.collections
Song Load (0.2ms)  SELECT "songs".* FROM "songs" ORDER BY "songs"."id" ASC LIMIT 1
NoMethodError: undefined method `klass' for nil:NilClass
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.0.0/lib/active_record/reflection.rb:420:in `block in source_reflection'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.0.0/lib/active_record/reflection.rb:420:in `collect'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.0.0/lib/active_record/reflection.rb:420:in `source_reflection'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.0.0/lib/active_record/reflection.rb:579:in `derive_class_name'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.0.0/lib/active_record/reflection.rb:133:in `class_name'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.0.0/lib/active_record/reflection.rb:178:in `klass'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.0.0/lib/active_record/reflection.rb:420:in `block in source_reflection'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.0.0/lib/active_record/reflection.rb:420:in `collect'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.0.0/lib/active_record/reflection.rb:420:in `source_reflection'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.0.0/lib/active_record/reflection.rb:557:in `check_validity!'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.0.0/lib/active_record/associations/association.rb:25:in `initialize'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.0.0/lib/active_record/associations/has_many_through_association.rb:9:in `initialize'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.0.0/lib/active_record/associations.rb:157:in `new'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.0.0/lib/active_record/associations.rb:157:in `association'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.0.0/lib/active_record/associations/builder/association.rb:70:in `collections'
    from (irb):3
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/railties-4.0.0/lib/rails/commands/console.rb:90:in `start'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/railties-4.0.0/lib/rails/commands/console.rb:9:in `start'
    from /Users/jonathan/.rvm/gems/ruby-1.9.3-p392/gems/railties-4.0.0/lib/rails/commands.rb:64:in `<top (required)>'
    from bin/rails:4:in `require'

有人可以告诉我我在这里做错了什么。好像没有看到歌曲与收藏的关系?我只是不知道我做错了什么。

正如@damien在评论中指出的那样,我需要更改:

has_many :collectionitems, through: :collectable

自:

has_many :collectionitems, as: :collectable

一旦到位,一切都按预期工作。

再次感谢@damien!

最新更新