Rails:在模块/关注点中根据父类名称动态定义类方法

11
我想要动态生成一个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}"

但似乎这些都没起到作用 :/

我能否找到一种方法来检索基类名称(不确定如何称呼包含我的模块的类)。我已经为此问题苦苦挣扎了几个小时,但似乎找不到一个简洁的解决方案 :(

谢谢!

4个回答

8
我发现了一个简洁的解决方案:使用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  

7

您不能这样做 - 目前还不知道包含该模块的类(或类)是哪个。

如果定义了self.included方法,每次包含模块时都会调用它,并将进行包含的对象作为参数传递。另外,由于您正在使用AS::Concern,因此可以执行以下操作:

included do 
  #code here is executed in the context of the including class
end

3
谢谢解释。我在included do #... end块中使用了define_singleton_method方法:define_singleton_method "#{self.name}_status" do #... end - cl3m

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接