web-dev-qa-db-ja.com

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

エラーメッセージが表示されます。

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

チュートリアルは問題がないことを示しており、コードが正常であることを知っています。他の関連する質問を検索しましたが、それらはすべてRuby 2から3またはerb vs eruby。

56
Matthew Chan

すでに他の場所でWordクラスが定義されています。 Rails 3アプリ内で試しましたが、複製できませんでした。

2番目のWordクラスを自分で作成していない場合は、Gemsまたはプラグインのいずれかで既に定義されている可能性があります。

71

これも次のように発生する可能性があります。

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

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

class Document < ActiveRecord::Base
  include Geocoder
end

Requireは、Document < ActiveRecord::Base(異なるスーパークラスを持つ)の前にDocument(Objectのスーパークラスを持つ)をロードします。

Rails環境では、クラスの自動ロード機能を備えているため、通常requireは必要ありません。

24
Kris

Rails 4アプリケーションで問題が発生しました。ユーザー名前空間で懸念事項を使用しました。

class User
  module SomeConcern
  end
end

開発ではすべて正常に機能しましたが、本番では(preload_appがtrueであるためだと思います)不一致エラーが発生しました。修正は非常に簡単でした。初期化子を追加しました。

require "user"

乾杯!

17
2called-chaos

今、これと同じ問題がありました。基本的に、それはWordが他の場所でクラスとして定義されていることを意味します。 WordをWord2に変更するだけで、チュートリアルで正常に機能するはずです。

6
RebelWarrior

時々私たちは知らないうちに「クラスを開く」。たとえば、いくつかの深いモジュールのネストの場合:

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

# space_gun/trigger.rb
class SpaceGun
  class Trigger
  end
end

トリガーを定義するとき、既存のSpaceGunクラスを開きます。これは動作します。ただし、2つのファイルを逆の順序で読み込むと、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

どちらか

  1. 自動ロードに依存する
  2. 常にすべての開いているクラスのオカレンスに継承を置きます。
3
lulalala