Rails: IST, héritage et rechargement ! bogue dans l'environnement de développement

Créé le 2 janv. 2013  ·  3Commentaires  ·  Source: rails/rails

Je rouvre le numéro 868 car il est toujours présent aujourd'hui.

J'ai utilisé ruby-1.9.3-p362 et rails 3.2.9

La seule solution est d'exiger des classes enfants ou d'utiliser config.cache_classes = true

> Support.all
 => [] 
> Employee
 => Employee(id: integer, type: string) 
> Administrator
 => Administrator(id: integer, type: string) 
> Support.all
 => [#<Administrator id: 1, type: "Administrator">, #<Employee id: 2, type: "Employee">] 
activerecord

Commentaire le plus utile

Il s'agit d'une limitation connue de l'utilisation de STI en mode développement avec chargement paresseux des classes. Vous devez utiliser require_dependency pour informer Rails de ces sous-classes, par exemple :

# app/models/support.rb
class Support < User
end

require_dependency 'administrator'
require_dependency 'employee'

Si vous avez beaucoup de ces sous-classes, vous pouvez utiliser Dir[] et un dossier spécial dans app pour les charger toutes, par exemple :

# app/models/user.rb
class User < ActiveRecord::Base
end

Dir["#{Rails.root}/app/users/*.rb"].each do |file|
  require_dependency file
end

Ou une troisième alternative consiste à coder en dur la liste en Model.descendants , par exemple :

# app/models/user.rb
class User < ActiveRecord::Base
  def self.descendants
    [Support, Administrator, Employee]
  end
end

Je n'ai pas utilisé le dernier personnellement mais cela devrait fonctionner.

Tous les 3 commentaires

Je l'ai reproduit sur rails 4

Rails 4.0.0.beta
Rubis 1.9.3p194

1.9.3p194 :001 > Administrator.create

1.9.3p194 :003 > Employee.create

1.9.3p194 :008 > Support.all
  Support Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."type" IN ('Support', 'Administrator', 'Employee')
 => #<ActiveRecord::Relation [#<Administrator id: 1, type: "Administrator">, #<Employee id: 2, type: "Employee">]> 

1.9.3p194 :009 > reload!
Reloading...
 => true 

1.9.3p194 :010 > Support.all
  Support Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."type" IN ('Support')
 => #<ActiveRecord::Relation []> 

Il s'agit d'une limitation connue de l'utilisation de STI en mode développement avec chargement paresseux des classes. Vous devez utiliser require_dependency pour informer Rails de ces sous-classes, par exemple :

# app/models/support.rb
class Support < User
end

require_dependency 'administrator'
require_dependency 'employee'

Si vous avez beaucoup de ces sous-classes, vous pouvez utiliser Dir[] et un dossier spécial dans app pour les charger toutes, par exemple :

# app/models/user.rb
class User < ActiveRecord::Base
end

Dir["#{Rails.root}/app/users/*.rb"].each do |file|
  require_dependency file
end

Ou une troisième alternative consiste à coder en dur la liste en Model.descendants , par exemple :

# app/models/user.rb
class User < ActiveRecord::Base
  def self.descendants
    [Support, Administrator, Employee]
  end
end

Je n'ai pas utilisé le dernier personnellement mais cela devrait fonctionner.

J'ai ce genre de problème et je n'arrive pas à le faire fonctionner. Mes modèles sont A, B (et plus) < C, D (et plus) < B.
Après un changement de code, j'obtiens une "constante B non initialisée". J'ai essayé require_dependency de plusieurs manières, mais je ne sais pas vraiment 1) quelle(s) classe(s) exiger (B ?), et 2) où le faire.
Ces modèles sont associés à d'autres modèles de plusieurs manières, cela peut également avoir un impact sur l'ordre de chargement (par exemple, A appartient_à X, X has_many Bs et Cs)

Cette page vous a été utile?
0 / 5 - 0 notes