views:

169

answers:

1

I'm rendering polymorphic records in a view by looping over the polymorphic records and choosing the appropriate partial to use for the polymorphic relationship. However when a user is administering the site each polymorphic record may (or may not) have a second (alternate) partial that should be used in that situation.

So currently I'm doing the following (pseudo code):

polymorphs.each do |poly|
    if File.exists?( File.join( RAILS_ROOT, 'app', 'views', poly.type, '_alternate.html.erb' ) )
        partial = "#{poly.type}/alternate"
    else
        partial = "#{poly.type}/original"
    end
    ...
end

This is working fine, but it's an obvious bottleneck. So I want to do these checks for the existence of these alternate partials once only and then cache them.

I did start down the road of doing this in an initializer but the downside there is that it only runs once in development and ideally I'd like to not have to restart the server just when I add a new alternate partial during development.

+2  A: 

Put it in a separate class method and use memoize on it.

class FooController
  class << self
    extend ActiveSupport::Memoizable
    def find_path_for(type)
      if File.exists?( File.join( RAILS_ROOT, 'app', 'views', poly.type, '_alternate.html.erb' ) )
        partial = "#{poly.type}/alternate"
      else
        partial = "#{poly.type}/original"
      end
    end
    memoize :find_path_for
  end
end
cwninja
The only thing missing for your example was I needed to include extend ActiveSupport::Memoizable after the class << self
DEfusion
Good point. Updated.
cwninja