开发者

How can I DRY up all these calls to render :index?

I have a bunch of controllers wi开发者_Go百科th methods that render the index view. This results in me writing render :index at the end of the majority of methods. Here's an example

def index
  @models = Model.find(:all)
end

def new_models
  @models = Model.find_by_new(true)

  render :index
end

def old_models
  @models = Model.find_by_new(false)

  render :index
end

Ideally, I would just move the render code into an after filter, but as the controller makes a call to render before going to the after filter that's not an option.

I have a large number of controllers like this so a solution would remove a lot of repeated code.

This app is currently still Rails 2.3, however, it will be upgraded to Rails 3 in the next month or two. So while I would prefer a technique that works on 2.3, Rails 3 only solutions would still be appreciated.


If you really want to DRY up this action, and if it's very common, then you can do some meta-programming of your own. First create a render_with_index.rb file with this module definition:

module RenderWithIndex
  def self.included klass
    klass.class_eval do
      def self.render_with_index * methods
        methods.each do |method|
          self.class_eval <<-EVAL
            alias :old_method :#{method}

            def #{method}
              old_method
              render :index
            end
          EVAL
        end
      end
    end
  end
end

Then include that module in your controller and define the methods that should render with index (make sure the render_with_index call happens after your method declarations.

include RenderWithIndex

def index
  @models = Model.find(:all)
end

def new_models
  @models = Model.find_by_new(true)
end

def old_models
  @models = Model.find_by_new(false)
end

render_with_index :new_models, :old_models

This module now allows you to render any action with the index template simply by adding it to the render_with_index call.


Looks pretty DRY to me. IMHO it's a good habbit to mention which template you are rendering if you don't want to use controller method specific template.

If your render code extends from one-liner into several lines of code, I would DRY them up into separate render method.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜