如何应用元编程来简化控制器?

时间:2012-03-21 15:37:23

标签: ruby-on-rails ruby controller metaprogramming

在我的widgets_controller.rb中,我有以下方法

# GET /widgets/index_of_deleted
def index_of_deleted
  @widgets = Widget.order("name").deleted

  respond_to do |format|
    format.html
  end
end

我还有很多其他会使用这种方法的模型。如何以通用形式创建具有此方法的模块,以便我可以干掉控制器?我认为解决方案就是打电话给这个..

index_of_deleted("widget")

..在我的widgets_controller.rb中。或者我可以使用控制器的名称,只在每个使用此方法的控制器中包含此模块?

具体来说,index_of_deleted的实现在我的模块中会是什么样的?

1 个答案:

答案 0 :(得分:2)

您可以编写模块并包含它们。首先在lib中创建一个文件,也许是这样的:

module WidgetExtras
  def index_of_deleted(widget)
    # implementation
  end
end

然后,在WidgetsController附近的顶部,简单地添加:

include WidgetExtras

您可能希望更明确地命名模块(只是嵌套它们)。

修改

我不确定是否值得抽象,有多少型号需要此功能?您可以编写帮助程序来查找已删除的项目:

module ApplicationHelper
  def deleted_for_class( klass )
    klass.order('name').deleted
  end
end

但是,为什么不只是为'名称'删除Model制作一个范围......

编辑2

您可以编写实现来设置实例变量...

def index_of_deleted( widget_name )
  klass = Kernel.const_get(widget_name.classify)
  instance_variable_set( "@#{widget_name.pluralize}", klass.order('name').deleted )
end