2010-08-27 3 views
1

Cette question est liée à l'extension des méthodes de classe dans Ruby, peut-être plus spécifiquement de la manière permalink_fu.Sous-classe ActiveRecord avec permalink_fu dans un moteur de rails

Il semble que has_permalink sur un modèle ne sera pas disponible dans un modèle dérivé. Certes, je m'attendrais à ce que tout ce qui est défini dans une classe soit hérité par ses classes dérivées.

class MyScope::MyClass < ActiveRecord::Base 
    unloadable 
    self.abstract_class = true 
    has_permalink :name 
end 

class MyClass < MyScope::MyClass 
    unloadable 
    #has_permalink :name # This seems to be required 
end 

Y a-t-il quelque chose dans la façon dont permalink_fu se mélange à cause de ce problème?

J'utilise la pierre précieuse permalien-v.1.0.0 http://github.com/goncalossilva/permalink_fu

Répondre

0

Après avoir étudié, je peux maintenant voir que le problème est lié à la façon dont il permalink_fu vérifie qu'il devrait créer un lien permanent ou non. Il vérifie cela en vérifiant si le champ permalink_field de la classe est vide ou non.

Qu'est-ce que le champ permalink_field? Lorsque vous faites

class Parent < ActiveRecord::Base 
    has_permalink :name 
end 

class Child < Parent 
end 

vous pouvez accéder à ce permalien en écrivant Parent.new.permalink ou Child.new.permalink. Ce nom de la méthode peut être modifiée en écrivant

class Parent < ActiveRecord::Base 
    has_permalink :name 'custom_permalink_name' 
end 

Si oui, ce permalien sera accessible en écrivant Parent.new.custom_permalink_name (ou Child.new.custom_permalink_name).

Quel est le problème avec cela? Les méthodes accesseurs permalink_field sont définies sur métaclasse de Parent:

class << self 
    attr_accessor :permalink_field 
end 

Lorsque vous exécutez la méthode has_permalink, il appelle Parent.permalink_field = 'permalink'.

Le problème est que, bien que la méthode permalink_field est disponible sur toutes les sous-classes, sa valeur est stockée sur la classe, il a été appelé. Cela signifie que la valeur n'est pas propagée aux sous-classes. Donc, comme le permalink_field est stocké dans la classe Parent, l'enfant n'hérite pas de la valeur, bien qu'il hérite des méthodes d'accès. Comme Child.permalink_field est vide, le should_create_permalink? renvoie false et Child.create :name => 'something' ne crée pas de permalien.

Une solution possible serait de remplacer les attr_acessors de la métaclasse par cattr_accessors sur la classe (lignes 57 à 61 du fichier permalink_fu.rb).

Remplacer

class << base 
    attr_accessor :permalink_options 
    attr_accessor :permalink_attributes 
    attr_accessor :permalink_field 
end 

avec

base.cattr_accessor :permalink_options 
base.cattr_accessor :permalink_attributes 
base.cattr_accessor :permalink_field 

Notez que cela annulerait toute personnalisation possible sur la sous-classe. Vous ne pourrez plus spécifier d'options différentes pour les sous-classes, car ces trois attributs sont partagés par Parent et toutes ses sous-classes (et sous-classes).

+0

Merci pour l'aide, cela m'a définitivement permis de démarrer. – aceofspades

Questions connexes