views:

1337

answers:

3

I have two controllers for two respective models, by example, photos and categories. index and show methods are very similar in each controller, and the views are identical. What is the best method for share the view by the two models?

I've though two options:

  • Use a helper. In the helper will put the code for the view, and will call the helper from each view (photos/views and categories/views)

  • Use a partial in each views. I think it's a more clean solution, but I see huge DRY's in my mind when going to code this solution.

So, I have two controllers from two models, each one at and exposes a @photo object (photos controller with all the photos, and categories controller with just the selected categorie's photos) and I need one view to show both.

I'm looking for an elegant solution for this, complaining REST and DRY principes. Any idea?

Thanks in advance.

+1  A: 

I'd use an helper because they are shared among views. For the HTML part, I'd use partials so it would be a mix of both ways.

Keltia
Yes, i think it's the best solution due to its visibility from every controller or view, but, is it correct to put view code (html code) in a helper?
ARemesal
It'd be better to not put view code in the helpers unless it is less than a few lines
bjeanes
I'd use a mix of partial for the HTML code and helpers for the code.
Keltia
+7  A: 

I have a similar situation with one of my projects. All the delete views for most controllers are styled the same way, display the same confirmation boxes, and simply renders a predictable display of whatever object is being deleted.

The solution was quite simple and elegant in my opinion. Simply put, what we (the developers) did was create a new directory in app/views called shared and put shared views in there. These could be full template files or just partials.

I would suggest using a shared template (in neither categories nor photos view directories, but rather in the shared directory) and rendering it manually from the view.

e.g. have a method as such in both controllers and a file app/views/shared/photo.html.erb:

def show
  @photo = Photo.first # ... or whatever here
  render :template => 'shared/photo'
end

This should successfully render the shared template. It is the DRYest route and doesn't have the feeling of pollution you get when using a more-or-less empty view in each controller's view directory just to include a shared partial, as I understand your question is suggesting.

bjeanes
+2  A: 

About the first answer:

If the partial must be rendered from a view:

<%= render :partial => "shared/photo" %>

and the partial must be in app/views/shared/_photo.html.erb

Rodrigo