6
\$\begingroup\$

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?

Are there any "gotchas" I might encounter doing it this way?

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).

Malachi
29k11 gold badges86 silver badges188 bronze badges
asked Oct 10, 2012 at 18:18
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

This actually looks pretty solid.

Another approach would be to sub-class the Renderer and make it responsible for retrieving the base classes' to_partial_path.

For me this feels a bit cleaner because it is sub-classing versus monkey-patching and because the renderer is supposed to find and load the template anyway while the model class shouldn't case about the (non-)existence of the view at all.

After looking at it for a while, I would the make sub-classes partial_path check if the template exists and find the template of the base class if it doesn't.

answered Oct 22, 2013 at 19:25
\$\endgroup\$
1
  • 1
    \$\begingroup\$ How would you let Rails know that it should use the PartialRenderer subclass? Is their a hook for that (I haven't found one)? \$\endgroup\$ Commented May 7, 2014 at 22:36

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.