ruby-on-rails - 如何以 "dynamically"打开一个类以便向其添加一个使用局部变量的作用域方法?

标签 ruby-on-rails ruby class module metaprogramming

我正在使用 Ruby on Rails v3.2.2。在一个模块中,我试图“动态”打开一个类,以便向它添加一个使用局部变量的 Ruby on Rails“范围方法”,这样:

module MyModule
  extend ActiveSupport::Concern

  included do
    # Note: The `CLASS_NAME` is not the class where `MyModule` is included. That
    # is, for instance, if the including class of `MyModule` is `Article` then
    # the `CLASS_NAME` is `User`.
    CLASS_NAME           = self.get_class_name.constantize # => User
    counter_cache_column = self.get_counter_cache          # => "counter_count"

    class CLASS_NAME
      def self.order_by_counter
        order("#{counter_cache_column} DESC")
      end
    end
  end
end

如果我运行上面的代码,我会得到以下错误:

NameError
undefined local variable or method `counter_cache_column' for #<Class:0x0000010775c558>

这是因为 counter_cache_column 没有在模块的上下文中调用。我应该如何正确说明 order_by_counter 范围方法?


奖励:您对上述“如此动态”的实现有何建议?

最佳答案

ActiveSupport::Concern 提供的included block 在包含类的范围内进行评估。换句话说,您已经“重新打开”了这个 block 中的类。如果包含类继承自 ActiveRecord::Base,您可以使用任何 AR 类宏,例如scopehas_manyattr_accessible等:

module MyModule
  extend ActiveSupport::Concern

  included do
    scope :order_by_counter, order("#{self.get_counter_cache} DESC")
  end

end

这假设“get_counter_cache”已被定义为包含类中的类方法(尽管从您显示的代码中看不清楚)。

关于ruby-on-rails - 如何以 "dynamically"打开一个类以便向其添加一个使用局部变量的作用域方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12914109/

相关文章:

ruby-on-rails - 在任何来源中都找不到 rake-10.4.2 (Bundler::GemNotFound)

python - 无法调用类 bark()

ruby-on-rails - Rails 4 迁移:Mysql2::Error:列 'xxxx' 的数据太长

Mysql2::错误: key '32012' 的重复条目 'PRIMARY'

javascript - 使用 Watir 测试 pirobox(类似灯箱)模态

ruby-on-rails - 如何解决这个 Railties 兼容性问题?

ruby - 检查变量是否为整数

ruby - ruby 中的惯用对象创建

objective-c - 在 Objective C 中,如何在运行时获取 self 的类名?

python - 为什么非空槽不能与 int、tuple、bytes 子类一起使用?