Where to put partials shared by the whole application in Rails?
Where would I go about placing partial files shared by more than one model?
I have a page called crop.html.erb
that is used for one model - Photo
.
Now I would like to use it for another model called User
as well.
I could copy and paste the code but that's not very DRY, so I figured I would move it into a partial.
Since it's shared between two models - where would I place that partial?
Thanks!
Solution 1:
The Rails convention is to put shared partials in /app/views/shared
.
Solution 2:
Update
Layout inheritance is now in the guides under layout and rendering Template inheritance works similarly.
Rails 3.1 and following versions implement template inheritance, so I think the correct place for shared partials is now /app/views/application/
, say you are in products#index
you can do the following:
-# products#index
= render @products.presence || 'empty'
-# /app/views/application/_empty.html.haml
There are no items
btw it's application
because the connection is the controller inheritance, so this assumes ProductsController < ApplicationController
This way if you implement /app/views/products/_empty.html.haml
that will be taken, the above is a fallback for all the missing partials, and I can't check right now, but I think even for the template itself...
Railscast: template inheritance!
Solution 3:
TL;DR
Rails 3.1, Rails 4, Rails 5 and whatever comes next
app/views/application
The engine searches this path automatically if the view is not found in the controller path.
Rails 3 and prior
app/views/shared
The engine does NOT search this path automatically.
Long story
Rails 3 (and prior version) have no default location for storing shared views.
The unofficial convention is to store shared views in app/views/shared. Wherever you'd end up storing them though, you have to specify the path
# render app/views/shared/menu.html.erb
<%= render :partial => "shared/menu" %>
This suggestion was popularized by Agile Web Development with Rails.
Rails 3.1 introduces an official standard for where to store shared views:
app/views/applicationThanks to this standard, the engine now automatically looks for templates in app/views/application. As a result, you don't have to use the full path anymore.
Those curious can follow here the thought process behind this decision.
Old syntax
# render app/views/application/menu.html.erb
# unless menu.html.erb is found in appp/views/my_controller
<%= render :partial => "menu" %>
New syntax
# render app/views/application/menu.html.erb
# unless menu.html.erb is found in appp/views/my_controller
<%= render partial: "menu" %>
Of course, you can still place your shared views wherever you want and reference them by path
<%= render :partial => "my_own_special_shared_folder/menu" %>
Unless you have a very good reason to do this though, please stick to the new standard and store your shared views in app/views/application
.
Solution 4:
The Rails View uses app/views/layouts
for shared partials like header and footer, but the Ruby on Rails Guide uses app/views/shared
in an example. I guess it comes down to personal preference. I would use layouts
for high-level stuff like a main nav or a footer, but shared
for more narrow controller-level stuff like a form.
Solution 5:
I general have a shared folder in my views that contains commonly used partials.