多态has_many:通过NoMethodError:未定义的方法`klass'代表nil:NilClass

时间:2013-08-28 20:30:49

标签: ruby-on-rails relationship has-many-through polymorphic-associations

所以我开始在我的应用程序中设置has_many:through polymorphic association。模型如下所示:

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 =&gt;返回第一个集合的歌曲数组 Collection.first.albums =&gt;返回第一个集合的专辑数组 Collectionitem.first.collection =&gt;返回此Collectionitem所属的集合 Collectionitem.first.collectable =&gt;返回此Collectionitem所属的记录(歌曲或专辑)

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

在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'

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

1 个答案:

答案 0 :(得分:2)

@damien在评论中指出我需要改变:

has_many :collectionitems, through: :collectable

到:

has_many :collectionitems, as: :collectable

一旦这个到位,每个标志都按预期工作。

再次感谢@damien!