Rails is very helpful when it comes to automatically rendering a partial for a given object.
<% @startups.each do |startup| %> <%= render startup %> <!-- Renders startups/startup partial --> <% end %>
This loop renders the
startups/startup partial for every startup in the collection. If you want to
change the partial it renders, you can override the
#to_partial_path method on your object like this.
class Startup < ActiveRecord::Base def to_partial_path 'startups/summary' end end
This is great if you want change the partial path for all startup objects in your application. How about if you want to change the partial path only in a specific view?
Overriding #to_partial_path with a decorator
One approach is to use the decorator pattern wrap the model and override only the #to_partial_path method.
class StartupTile < SimpleDelegator def to_partial_path 'startups/tile' end end StartupTile.new(Startup.new).to_partial_path #=> "startups/tile"
However, it can be very inconvenient to create a new class every time you want to customize an object’s partial path.
There’s a gem for that
We decided to generalize this solution and turn it into the
partial_path_customizer gem. This gem
includes a single method in your view helpers called
<!-- Renders the "startups/tile" partial --> <%= render customize_partial_path(startup, 'tile') %>
This code decorates the startup object and overrides
#to_partial_path so it returns
This also gets useful when you have a collection of multiple types of objects, possibly from a
# Somewhere in the controller @employees = [Developer.new, Designer.new, Developer.new] # Then in the view <%= render customize\_partial\_path(@employees, 'summary') %>
This renders the
developers/summary partials, respectively.
The partial_path_customizer gem solves
the problem of wanting to use Rails implicit rendering, but only being able to use it for one partial
per object. Since this gem only wraps the object being rendered, you can still pass all of normal
options to the
#render that allow you to do things like caching partials.
<%= render customize\_partial\_path(@developers, 'summary'), cache: true %>
If you’d like to learn more about the basics of
#to_partial_path, check out this blog
Please send us feedback on Twitter and let us know what you think.
Originally published at blog.animascodelabs.com on October 9, 2014.