我想基于包含此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
但是这给了我以下方法名称:
MyClass.mymodule::classmethods_status
在方法定义中获取基类名称(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}"
但这似乎没有做到这一点:/
有没有办法可以检索基类名称(不知道该怎么称为包含我的模块的类)。我几个小时以来一直在努力解决这个问题,我似乎无法找到一个干净的解决方案:(
谢谢!
答案 0 :(得分:6)
你不能这样做 - 在这一点上还不知道哪个类(或类)包含模块。
如果定义self.included
方法,则每次包含模块时都会调用它,并且执行包含的内容将作为参数传递。或者,因为您使用AS :: Concern,您可以
included do
#code here is executed in the context of the including class
end
答案 1 :(得分:6)
我找到了一个干净的解决方案:使用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
答案 2 :(得分:1)
您可以这样做:
module MyModule
def self.included(base)
(class << base; self; end).send(:define_method, "#{base.name.downcase}_status") do
puts "Hey!"
end
base.extend(ClassMethods)
end
module ClassMethods
def other_method
puts "Hi!"
end
end
end
class MyClass
include MyModule
end
MyClass.myclass_status
MyClass.other_method
答案 3 :(得分:1)
适用于extend
:
module MyModule
def self.extended who
define_method "#{who.name.downcase}_status" do
p "Inside"
end
end
end
class MyClass
extend MyModule
end
MyClass.myclass_status