我想基于包含此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}"
但这似乎没有做到这一点:/
有什么方法可以检索基类名称(不知道该怎么称为包含我的模块的类)。我一直在努力解决这个问题几个小时,我似乎无法找到一个干净的解决方案:(
谢谢!
你不能这样做 - 在这一点上还不知道哪个类(或类)包含模块。
如果你定义一个 self.included
每次包含模块时都会调用它,并且执行包含的东西将作为参数传递。或者,因为您使用AS :: Concern,您可以这样做
included do
#code here is executed in the context of the including class
end
你不能这样做 - 在这一点上还不知道哪个类(或类)包含模块。
如果你定义一个 self.included
每次包含模块时都会调用它,并且执行包含的东西将作为参数传递。或者,因为您使用AS :: Concern,您可以这样做
included do
#code here is executed in the context of the including class
end
我发现了一个干净的解决方案:使用 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
你可以这样做:
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
效劳于 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