【问题标题】:Polymorphic has_many :through NoMethodError: undefined method `klass' for nil:NilClass多态has_many:通过NoMethodError:nil:NilClass的未定义方法`klass'
【发布时间】:2013-09-01 02:24:09
【问题描述】:

所以我开始在我的应用程序中设置一个 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 所属的集合 Collectionitem.first.collectable => 返回此 Collectionitem 所属的记录(歌曲或专辑)

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

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

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'

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

【问题讨论】:

  • 我认为through: :collectable 应该是as: :collectable
  • 那行得通@Damien!非常感谢。我能问一下你是怎么知道的吗?它是否记录在某个地方,rails 4 发生了变化?
  • 太棒了!是的,它记录在 Rails 指南中:guides.rubyonrails.org/…。尽管您可能已经涵盖了大部分内容,但绝对值得多看几遍指南。

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


【解决方案1】:

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

has_many :collectionitems, through: :collectable

到:

has_many :collectionitems, as: :collectable

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

再次感谢@damien!

【讨论】:

  • 我有一个非常相似的问题,但我没有看到 :collectable 在您的问题中作为一个类被提及。
  • :collectable 不是一个类它是多态赋值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-26
  • 1970-01-01
  • 1970-01-01
  • 2014-07-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多