Ruby / Rails元编程:动态生成辅助方法

时间:2011-06-08 13:43:50

标签: ruby-on-rails ruby ruby-on-rails-3 metaprogramming dynamically-generated

我正在尝试为给定的模型名称数组动态生成一些计数方法,然后我可以在视图/帮助器中使用它们:

  # create dynamic count methods for each model we want                   
  ['model', 'other_model', 'next_model'].each do |name|
     class_eval{
       "def total_#{name.underscore}s_count
          total_#{name.underscore}s_count ||= #{name.camelcase}.all.count
        end"
      }
  end

但是,我有几个问题:

  1. 如果我希望能够在视图中调用这些方法,那么此代码应该放在哪里?
  2. 这些方法会添加到哪个类?例如,我如何调用它们,因为我不确定它们是否属于User等等类,因为它们适用于一堆模型。
  3. 有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

您应该使用mixin并将其包含在相关的模型类中。 http://juixe.com/techknow/index.php/2006/06/15/mixins-in-ruby/

这些方法将在您视图中的模型实例上提供。

答案 1 :(得分:1)

您尝试解决的问题(保持您的视图不会遇到模型方法)无法通过将相同的逻辑委托给视图助手来解决。如果你想坚持MVC惯例,保持你的视图不会触发SQL查询,你应该在控制器中执行此操作。

def index
  models = Foo, Bar, Bat
  @counts = models.inject({}) do |result, model|
    result[model.name.downcase.to_sym] = model.count
    result
  end
end

然后,您可以对所传递的每个模型的计数进行很好的哈希:

@counts #=> { :foo => 3, :bar => 59, :bat => 42 }