# Sharing view code across actions with the same function

**URL:** <https://www.ruby-forum.com/t/sharing-view-code-across-actions-with-the-same-function/114354>\
**Category:** Rails\
**Created:** [September 11, 2007, 5:51pm UTC](https://www.ruby-forum.com/t/sharing-view-code-across-actions-with-the-same-function/114354 "2007-09-11T17:51:20Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![acgreen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/3bc359/32.png) [@acgreen](https://www.ruby-forum.com/u/acgreen)\
**Post date:** [September 11, 2007, 5:51pm UTC](https://www.ruby-forum.com/t/sharing-view-code-across-actions-with-the-same-function/114354/1 "2007-09-11T17:51:20Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![acgreen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/3bc359/32.png) [@acgreen](https://www.ruby-forum.com/u/acgreen)\
**Post date:** [September 12, 2007, 7:54am UTC](https://www.ruby-forum.com/t/sharing-view-code-across-actions-with-the-same-function/114354/2 "2007-09-12T07:54:12Z")

</div>

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. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![acgreen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/3bc359/32.png) [@acgreen](https://www.ruby-forum.com/u/acgreen)\
**Post date:** [September 12, 2007, 3:06pm UTC](https://www.ruby-forum.com/t/sharing-view-code-across-actions-with-the-same-function/114354/3 "2007-09-12T15:06:32Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![acgreen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/3bc359/32.png) [@acgreen](https://www.ruby-forum.com/u/acgreen)\
**Post date:** [September 13, 2007, 10:25am UTC](https://www.ruby-forum.com/t/sharing-view-code-across-actions-with-the-same-function/114354/4 "2007-09-13T10:25:23Z")

</div>

Ryan wrote:

> On Sep 12, 8:06 am, Anthony G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> 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](http://www.codefluency.com/assets/2007/5/18/VisForVexing.pdf)

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

> **[no content for you!](https://thoughtbot.com/blog/no-content-for-you)**
>
> Conditional display of application components.

---

<div class="post-metadata">

**Author:** ![acgreen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/3bc359/32.png) [@acgreen](https://www.ruby-forum.com/u/acgreen)\
**Post date:** [September 13, 2007, 3:35am UTC](https://www.ruby-forum.com/t/sharing-view-code-across-actions-with-the-same-function/114354/5 "2007-09-13T03:35:45Z")

</div>

On Sep 12, 8:06 am, Anthony G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
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.

---

<div class="post-metadata">

**Author:** ![acgreen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/3bc359/32.png) [@acgreen](https://www.ruby-forum.com/u/acgreen)\
**Post date:** [September 17, 2007, 1:25pm UTC](https://www.ruby-forum.com/t/sharing-view-code-across-actions-with-the-same-function/114354/6 "2007-09-17T13:25:14Z")

</div>

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. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
