2009-07-17 6 views
3

J'ai un modèle AbstractRecord à partir duquel certains des modèles concrets (qui ont leurs propres tables) descendent. Voici l'héritage.Rails: Comment utiliser efficacement self.inherited

AbstractRecord < ActiveRecord::Base 
Blog < AbstractRecord 
Post < AbstractRecord 
.... 
.... 

Pour Rails pour rechercher les tables appropriées s'il y a l'héritage, l'API docs dire de définir une méthode de classe abstract_class? cela revient vrai pour que les rails ne cherchent pas sa table. Dans mon cas, pour que les rails recherchent la table des blogs (au lieu de la table abstract_records, ce qui est typiquement le cas comme dans STI) j'ai défini la méthode abstract_class? dans AbstractRecord qui renvoie true. Toutes les requêtes semblent fonctionner correctement. Mais je vois à chaque fois que j'instancie Blog, rails le montre comme Blog (abstract) dans la console comme sa classe parente renvoie true. Pour éviter cela, je pourrais à nouveau définir abstract_class? qui renvoie false dans la classe Blog.

Mais je pensais au lieu de définir abstract_class? dans tous les modèles enfants, si je pouvais en quelque sorte utiliser self.inherited et définir cette méthode dans AbstractClass elle-même. J'ai essayé d'utiliser plusieurs approches (suite) aucune ne semble fonctionner.

class AbstractRecord < ActiveRecord::Base 
def self.abstract_class? 
    true 
end 

def self.inherited(subclass) 
    super 
    subclass.instance_eval do 
    define_method(:abstract_class?) { false } 
    end 
end 
end 

class AbstractRecord < ActiveRecord::Base 
def self.abstract_class? 
    true 
end 

def self.inherited(subclass) 
    super 
    subclass.class_eval do 
    define_method(:abstract_class?) { false } 
    end 
end 
end 

class AbstractRecord < ActiveRecord::Base 
def self.abstract_class? 
    true 
end 

def self.inherited(subclass) 
    super 
    subclass.instance_eval do 
    def abstract_class? 
    false 
    end 
    end 
end 
end 

class AbstractRecord < ActiveRecord::Base 
def self.abstract_class? 
    true 
end 

def self.inherited(subclass) 
    super 
    subclass.class_eval do 
    def abstract_class? 
    false 
    end 
    end 
end 
end 

Tout ce que je conseille fais mal est apprécié?

Répondre

1
class Account < Foo::Bar::Base 
end 

module Foo 
    module Bar 
    class Base < ::ActiveRecord::Base 
     def self.abstract_class? 
     true 
     end 
    end 
    end 
end 

Cela fonctionne bien pour moi. Il en résulte un nom de table "comptes" comme il se doit.

2

Essayez ceci:


def self.inherited(subclass) 
    super 
    def subclass.abstract_class? 
    false 
    end 
end 

Ou:


def self.inherited(subclass) 
    super 
    subclass.class_eval do 
    def self.abstract_class? 
    # You lost the 'self' part, so you had just defined an instant method for the subclass 
     false 
    end 
    end 
end 

+0

vote en raison de ne pas obtenir le nom de la méthode 'hérité' à droite! –

+0

@BillEisenhauer Pourquoi ne pas suggérer un montage plutôt qu'un vote négatif? – Nick

+0

@Nick Je n'en ai aucune idée! Vous parlez d'une action que j'ai prise il y a près de 5 ans. Peut-être que je ne savais pas comment suggérer un montage à ce moment-là? Je savais probablement que la réponse n'était pas correcte et je voulais assurer que les autres n'étaient pas confus. –

Questions connexes