Ruby on Rails 3:"类的超类不匹配......"

Mat*_*han 56 ruby ruby-on-rails ruby-on-rails-3

平台:Mac OSX 10.6

在我的终端中,我使用"rails c"启动Ruby控制台

按照Ruby on Rails 3教程构建一个类:

class Word < String 
  def palindrome? #check if a string is a palindrome
    self == self.reverse
  end
end
Run Code Online (Sandbox Code Playgroud)

我收到错误消息:

TypeError: superclass mismatch for class Word
    from (irb):33
    from /Users/matthew/.rvm/gems/ruby-1.9.2-p180@rails3tutorial/gems/railties-3.0.5/lib/rails/commands/console.rb:44:in `start'
    from /Users/matthew/.rvm/gems/ruby-1.9.2-p180@rails3tutorial/gems/railties-3.0.5/lib/rails/commands/console.rb:8:in `start'
    from /Users/matthew/.rvm/gems/ruby-1.9.2-p180@rails3tutorial/gems/railties-3.0.5/lib/rails/commands.rb:23:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'
Run Code Online (Sandbox Code Playgroud)

教程显示它没有问题,我知道代码很好; 我搜索了其他相关问题,但他们都涉及从Ruby 2迁移到3或erb vs eruby.

Dou*_*rer 71

您已经在Word其他地方定义了一个类.我尝试在Rails 3应用程序中但无法复制.

如果您自己没有创建第二个Word类,很可能您的某个Gems或插件已经定义了它.

  • 谢谢,我最终重新启动了控制台.早些时候,我确实使用了不同的类名,却得到了同样的错误. (2认同)

Kri*_*ris 24

这也可以这样发生:

# /models/document/geocoder.rb
class Document
  module Geocoder
  end
end

# /models/document.rb
require 'document/geocoder'

class Document < ActiveRecord::Base
  include Geocoder
end
Run Code Online (Sandbox Code Playgroud)

require Document之前Document < ActiveRecord::Base(具有Object的超类)(具有不同的超类).

我应该注意,在Rails环境中,通常不需要require,因为它具有自动类加载.


2ca*_*aos 17

我遇到了Rails 4应用程序的问题.我在用户命名空间下使用了关注点.

class User
  module SomeConcern
  end
end
Run Code Online (Sandbox Code Playgroud)

在开发过程中一切正常,但在生产中(我猜因为preload_app为true)我得到了不匹配错误.修复非常简单.我刚添加了一个初始化器:

require "user"
Run Code Online (Sandbox Code Playgroud)

干杯!

  • @JeskTop 只需使用该单个文件将新文件添加到“config/initializers”即可。初始化程序在整个应用程序加载之前运行,并确保首先加载模型类。 (2认同)

小智 6

我现在遇到同样的问题.基本上这意味着Word被定义为其他地方的一个类,我的猜测是它在轨道宝石上.只需将Word更改为Word2,它应该在本教程中正常工作.


lul*_*ala 6

有时我们在不知情的情况下“公开课”。例如一些深层模块嵌套:

# space_gun.rb
class SpaceGun << Weapon
  def fire
    Trigger.fire
  end
end

# space_gun/trigger.rb
class SpaceGun
  class Trigger
  end
end
Run Code Online (Sandbox Code Playgroud)

当我们定义触发器时,我们打开现有的 SpaceGun 类。这有效。但是,如果我们以相反的顺序加载这两个文件,则会引发错误,因为我们将首先定义 SpaceGun 类,但它不是武器。

有时我们会犯这个错误,因为我们显式地从父类中要求子模块(例如触发器)。这意味着类定义将以相反的顺序完成,从而导致此问题。

# surely nothing can go wrong if we require what we need first right?
require 'space_gun/trigger'
class SpaceGun << Weapon
  def fire
    Trigger.fire
  end
end
# BOOM
Run Code Online (Sandbox Code Playgroud)

任何一个

  1. 依赖自动加载
  2. 始终将继承放在每个开放类出现中。