Ruby on Rails 3: «incompatibilité de superclasse pour la classe…»

Plate-forme: Mac OSX 10.6

Dans mon terminal, je lance la console Ruby avec “rails c”

Tout en suivant le didacticiel Ruby on Rails 3 pour créer une classe:

class Word < String def palindrome? #check if a string is a palindrome self == self.reverse end end 

Je reçois le message d’erreur:

 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 `' from script/rails:6:in `require' from script/rails:6:in `' 

Le tutoriel montre qu’il n’y a pas de problème et que je sais que le code est correct. J’ai recherché d’autres questions connexes, mais elles impliquaient toutes la migration de Ruby 2 vers 3 ou erb vs eruby.

Vous avez déjà une classe Word définie ailleurs. J’ai essayé avec une application Rails 3 mais je n’ai pas pu répliquer.

Si vous n’avez pas créé vous-même une deuxième classe Word , il est probable que l’un de vos gems ou plugins le définisse déjà.

Cela peut aussi arriver comme tel:

 # /models/document/geocoder.rb class Document module Geocoder end end # /models/document.rb require 'document/geocoder' class Document < ActiveRecord::Base include Geocoder end 

Le requirejs charge le Document (qui a une super-classe d'object) avant le Document < ActiveRecord::Base (qui a une super-classe différente).

Je dois noter que dans un environnement Rails, le besoin n'est généralement pas nécessaire car il a un chargement automatique de classe.

J’ai eu le problème avec une application Rails 4. J’ai utilisé des préoccupations sous l’espace de noms de l’utilisateur.

 class User module SomeConcern end end 

En développement, tout fonctionnait bien, mais en production (je suppose qu’à cause de preload_app true), j’ai rencontré l’erreur de non correspondance. Le correctif était assez simple. Je viens d’append un initialiseur:

 require "user" 

À votre santé!

J’ai eu le même problème en ce moment. Fondamentalement, cela signifie que Word est défini comme une classe ailleurs et je pense que c’est sur le joyau des liens ferroviaires. Changez simplement Word en Word2 et cela devrait bien fonctionner sur le tutoriel.

Parfois, nous «ouvrons la classe» sans que nous le sachions. Par exemple avec une imbrication de module en profondeur:

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

Lorsque nous définissons le déclencheur, nous ouvrons la classe SpaceGun existante. Cela marche. Toutefois, si nous chargeons les deux fichiers dans l’ordre inverse, l’erreur sera déclenchée, car nous définirons d’abord une classe SpaceGun, mais ce n’est pas une arme.

Parfois, nous commettons cette erreur car nous exigeons explicitement un sous-module (par exemple un déclencheur) de la classe parente. Ce qui signifie que la définition de classe sera effectuée dans l'ordre inverse, ce qui provoquera ce problème.

 # surely nothing can go wrong if we require what we need first right? require 'space_gun/sortinggger' class SpaceGun << Weapon def fire Trigger.fire end end # BOOM 

Non plus

  1. compter sur le chargement automatique
  2. toujours mettre l'inheritance à chaque occurrence de classe ouverte.