ruby/datamapper: Refactor class methods to module
i've the following code and tried the whole day to refactor the class methods to a sperate module to share the functionality with all of my model classes.
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
I'd like to archive something like:
class Merchant
开发者_Go百科 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 )
But unfortunately, my ruby skills are to bad. I read a lot of stuff (e.g. here) and now i'm even more confused. I stumbled over the following two points:
alias_method
will fail, because it will dynamically defined in theDataMapper::Resource
module.- How to get a class method
allowed_properties
due including a module?
What's the ruby way to go?
Many thanks in advance.
Here is a good discussion on ruby class method module inheritance. Something like this could work:
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
Because it is using a form of inheritance you can take advantage of super
instead of using alias_method
, which many find to be more straight forward.
Using ModuleName::ClassMethods
is something you see alot in the Rails codebase and makes it easier to use super
.
精彩评论