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).
1 Answer 1
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.
-
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\$barelyknown– barelyknown2014年05月07日 22:36:56 +00:00Commented May 7, 2014 at 22:36