cl3*_*l3m 11 ruby module metaprogramming ruby-on-rails mixins
我想基于包含此Mixin的类名在Mixin中动态生成类方法.
这是我目前的代码:
module MyModule
extend ActiveSupport::Concern
# def some_methods
# ...
# end
module ClassMethods
# Here is where I'm stuck...
define_method "#{self.name.downcase}_status" do
# do something...
end
end
end
class MyClass < ActiveRecord::Base
include MyModule
end
# What I'm trying to achieve:
MyClass.myclass_status
Run Code Online (Sandbox Code Playgroud)
但这给了我以下方法名称:
MyClass.mymodule::classmethods_status
Run Code Online (Sandbox Code Playgroud)
获取方法定义中的基类名称(self,self.name ...),但我无法使其适用于方法名称...
到目前为止,我已经尝试过了
define_method "#{self}"
define_method "#{self.name"
define_method "#{self.class}"
define_method "#{self.class.name}"
define_method "#{self.model_name}"
define_method "#{self.parent.name}"
Run Code Online (Sandbox Code Playgroud)
但这似乎没有做到这一点:/
有什么方法可以检索基类名称(不知道该怎么称为包含我的模块的类).我几个小时以来一直在努力解决这个问题,我似乎无法找到一个干净的解决方案:(
谢谢!
你不能这样做 - 在这一点上还不知道哪个类(或类)包含模块.
如果定义一个self.included方法,每次包含该模块时都会调用它,并且执行包含的东西将作为参数传递.或者,因为您使用AS :: Concern,您可以这样做
included do
#code here is executed in the context of the including class
end
Run Code Online (Sandbox Code Playgroud)
我发现了一个干净的解决方案:使用define_singleton_method(在ruby v1.9.3中可用)
module MyModule
extend ActiveSupport::Concern
included do
define_singleton_method "#{self.name}_status" do
# do stuff
end
end
# def some_methods
# ...
# end
module ClassMethods
# Not needed anymore!
end
end
Run Code Online (Sandbox Code Playgroud)