2010-05-24 9 views
1

J'ai le code suivant et essayé toute la journée pour refactoriser les méthodes de classe à un module sperate pour partager la fonctionnalité avec toutes mes classes de modèle.ruby ​​/ datamapper: Méthodes de classe Refactor au module

Code (http://pastie.org/974847):

class Merchant 
    include DataMapper::Resource 

    property :id, Serial            
    [...] 

    class << self 
    @allowed_properties = [:id,:vendor_id, :identifier] 

    alias_method :old_get, :get 
    def get *args 
     [...] 
    end   

    def first_or_create_or_update attr_hash 
     [...] 
    end  
    end 

end  

Je voudrais archiver quelque chose comme:

class Merchant 
    include DataMapper::Resource 
    include MyClassFunctions 
    [...] 
end 

module MyClassFunctions 
    def get [...] 
    def first_or_create_or_update[...] 
end 

=> Merchant.allowed_properties = [:id] 
=> Merchant.get(:id=> 1) 

Mais malheureusement, mes compétences en rubis sont mauvais. J'ai lu beaucoup de choses (par exemple here) et maintenant je suis encore plus confus. Je suis tombé sur les deux points suivants:

  1. alias_method échouera, car il défini dynamiquement dans le module DataMapper::Resource.
  2. Comment obtenir une méthode de classe allowed_properties en raison notamment d'un module?

Quelle est la voie à suivre?

Merci beaucoup à l'avance.

Répondre

0

Here est une bonne discussion sur l'héritage de module de méthode de classe ruby. Quelque chose comme cela pourrait fonctionner:

module MyFunctions 
    module ClassMethods 
    @allowed_properties = [:id,:vendor_id, :identifier] 

    def get *args 
     opts = super_cool_awesome_sauce 
     super opts 
    end 

    def first_or_create_or_update[...] 
    end 
    end 

    def self.included(base) 
    base.extend(ClassMethods) 
    end 
end 

class Merchant 
    include DataMapper::Resource 
    include MyFunctions 
    [...] 
end 

Parce qu'il utilise une forme d'héritage, vous pouvez profiter de super au lieu d'utiliser alias_method, dont beaucoup trouvent être plus simple.

En utilisant ModuleName::ClassMethods est quelque chose que vous voyez beaucoup dans le code base de Rails et rend plus facile à utiliser super.

Questions connexes