Question

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!

Was it helpful?

Solution

The Rails convention is to put shared partials in /app/views/shared.

OTHER TIPS

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!

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/application

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

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.

I general have a shared folder in my views that contains commonly used partials.

It doesn't matter where you put them. You can render any partial at any arbitrary location by providing the file's path to render - it doesn't need to be associated with the controller that's rendering it. I use a directory simply called partials under the view directory, and call partials in it like this:

render :partial => 'partials/mypartial'
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top