[英]Rails: dynamically define class method based on parent class name within module/concern
我想基于包含此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
我发现了一个干净的解决方案:使用define_singleton_method
(在ruby define_singleton_method
可用)
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.