I have a STI table and want to be able to render a collection using

render @collection 

with every elements of the collection using their own partial or, if they don't have one, the parent partial. You know, partial inheritance.

So I added to my parent model :

def to_partial_path
  self.class._to_partial_path
end

protected

# a little hack to get partial inheritance in views, check if the partial exist, if not
# return the parent's one. Provide class level cache, be sure to restart your app when
# adding/removing partials.
def self._to_partial_path
  @_to_partial_path ||= begin
    element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self))
    collection = ActiveSupport::Inflector.tableize(self)
    if File.exists?(Rails.root.join('app', 'views', collection, "_#{element}.html.erb")) ||
    self.superclass == ActiveRecord::Base

      "#{collection}/#{element}"
    else
      self.superclass._to_partial_path
    end
  end
end

The original code is here.

This seems to work great so far but I want to have some opinions.

Should I have gone another way ?

Any gotcha I may find myself into using this ?

Any way to refactor this ?

edit: No problem whatsoever, it's working great for now. I'm looking for a way to achieve something similar with form (ie render form in new and edit views render the child _form partial if their is one, the parent one otherwise).

share|improve this question

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.