Sharing view code across actions with the same function

Does anyone have any techniques for sharing view code generators
(partials, helpers, yielding to content_for) across actions in different
controllers that essentionally do the same thing.

The biggest discernable weakness I’m finding at drying up views is
Rails’ view that there will be more commonality between view/actions
within a controller that view/actions (with the same name) across
controllers.

a form view that’s generated by episode/edit is going to have more in
common with the form view of series/edit that the table view of
episode/show

Tony

If you put your helpers in application_helper.rb, those methods are
available from all views.

You can also create shared partials that are accessible like this:

render :partial => ‘shared/edit’

You need to create a shared directory in the views directory. So
you’d have:

app/views/shared/_edit.rhtml

‘shared’ could be anything string, like ‘common’, etc. ‘shared’ is
what I’ve seen as a recommended name.

Ryan

On Sep 11, 10:51 am, Anthony G. [email protected]

Ryan wrote:

If you put your helpers in application_helper.rb, those methods are
available from all views.

That technique is only useful for calls to render within your
action_name view.rthml

If you need to put in in the layout/appliaction.rhtml file you have to
start putting conditional logic in order to decide whether to render the
partial or not.

application.rhtml

render :partial => ‘shared/editting_warning’ if controllers[:action] ==
edit

The best solution I can find is using yield and content_for but it makes
the views ugly

I thought one possible solution might be additional helpers based on a
combination of controller and action name available to the view. This
would allow you to add some grandularity to helpers usage.

Ryan wrote:

On Sep 12, 8:06 am, Anthony G. [email protected]
wrote:

render :partial => ‘shared/editting_warning’ if controllers[:action] == edit

You have to put the condition somewhere. What about putting it inside
the partial? Then your layout will read clean.

Putting condition logic in your views is bad. It makes for brittle code.

Read Bruce W.’ ‘V is for Vexing’ article on drying up views:

http://www.codefluency.com/assets/2007/5/18/VisForVexing.pdf

and Jared Carroll’s article ‘No Content for you’

On Sep 12, 8:06 am, Anthony G. [email protected]
wrote:

render :partial => ‘shared/editting_warning’ if controllers[:action] == edit

You have to put the condition somewhere. What about putting it inside
the partial? Then your layout will read clean.

Interesting read. I like the idea of using blocks instead of ‘if’
statements, it makes your code more declarative. It boils down to is
another layer of abstraction that moves the contract from being
between the view and the model/controller, to being between the view
and the helper module. That is a useful abstraction, as the helper
module will tend to only change when the view does. It also provides
a single point of impact if the under lying condition logic must be
changed. Thanks for the link, I will be adopting this style on future
work.

But a condition is still a condition, and conditionally yielding to a
block to hide an ‘if’ statement is just a fancy, albeit pretty,
condition. The purpose of hiding the condition in a helper is to make
the API more stable. When it comes to APIs of your own creation,
that’s a really useful thing as they tend to change more frequently
than core APIs. But you should be able to count on some things being
their now and in the future, especially when it comes to the
foundational libraries your application is built on. When testing
those types of conditions, I wouldn’t worry about hiding an ‘if’
statement inside a helper unless it was for the sake of readability.
On the subject of a layout, the following seems like readable, non-
fragile code to me:

<% case controller.action_name -%>
<% when ‘edit’ -%>
<%= render :partial => ‘shared/edit’ %>
<% when ‘show’ -%>
<%= render :partial => ‘shared/show’ %>
<% end -%>

Thinking about it further, I think I would put all of that in a
helper. That would make my layout look like this:

<%= shared_action_partial %>

In application_helper.rb I’d have:

def shared_action_partial
render :partial => ‘shared/’ + controller.action_name
rescue
#ignore error if partial does not exist
#re-throw error if it is some other type of error
end

This would seem to be very much in the Rails spirit, convention over
configuration. It adds another convention. If you have a shared/
partial, it will use it, otherwise nothing happens.

Again, thanks for the link.

Ryan

On Sep 13, 3:25 am, Anthony G. [email protected]