Rails: Presenters, Facades, and Helpers - where does the html markup go? - ruby-on-rails

In a fairly large rails application we are running into the issue of overly complex views. Most of the views have too much logic.
Views have between 2 and 4 related instance variables, and make use of various logic checks and helper methods to render the view.
Here is a fake example:
<% if authorized?(#user) %>
<!--some html-->
<% recent_projects(#projects).each do |project| %>
<!-- html & helper methods -->
<% end %>
<!--some more html-->
<% else %>
<!--some html & helper methods-->
<% end %>
Presenters, Facades, and helpers:
I've been researching using the facade and/or presenter pattern to help expose the functionality we need in the view while extracting and isolating the complexity.
My Question is:
Where does the html live? Do I make several small view partials and render them conditionally from helper methods? Do I create a presenter which has methods that handle the logic and output of the html (using content_tag, etc)?
Any general "best practices" or guidance would be appreciated. If I haven't been clear ask questions and I will respond quickly.

I'm unsure what the best practice is specifically but what I think is that making smaller view partials is the way to go so that the view code is separated and can be separately maintained. Your presentation logic resides inside a Presenter class and renders appropriate partials from app/views.
I think that using content_tag is going to make your UI designer think, say, how to add a css class to an element, ultimately leading to more maintenance time. content_tags are fine if they are smaller and are not frequently updated in terms of styling.
Another point to keep in mind is if you are a developer who is also after cleanliness of code then imagine writing a content_tag for multi-line block of <div /> with paragraph of text with multiple inner tags. You'd have to start manipulating strings to handle this and sometimes it become time consuming to yourself and other developers to follow the code.
I'm sure there are many more goodies of keeping the view template separate from Presenters but the point mentioned above is one that I learned from one of my recent projects.

Related

reusing the same table across several views in rails

Just learning rails and looking for best practices help. I have the same data table that is reused across several different views (index, search results) for my controller. In an attempt to keep it DRY I have the table code in a helper method using html<< for table HTML.
I realize that now I've pulled a chunk of my HTML into the controller which I'm not a big fan of. How is this situation of having a chunk of HTML you plan to reuse across several views handled best?
Thanks!
What you want are partials. You put the partials in the same folder as the views, but partials start with an underscore (e.g: app/views/user/_my_partial.html.erb). In this partial you can put the shared HTML code, and access it from the view with:
<%= render "my_partial" %>
Yes you skip the underscore when you access the partial.
See the rails guide for more information on partials.

Is it a good idea to create a helper method for this type of scenario?

I have this code in my html.erb at many places.
<div id="left-nav">
<%= render :partial => 'tests/tests_left_menu' %>
</div>
Is it a good idea to create helper method for this type of code ?
How to write this code in helper ?
I see a few good strategies to use in your situation. Pick and choose based on your project's specific requirements.
You can just put div#left-nav and its contents into yet another partial like tests/tests_left_menu_with_wrapper. This saves you a couple of lines.
If you can generalize the cases when the entire segment appears, you can move it into a layout. This way, once you declare the layout for a particular action using the ActionController::Base.layout method, you'll be able to skip writing the entire segment altogether.
You can write a helper, but it's not clear what advantage it confers over simply using content_tag. You're probably better off using partials or layouts.
Personally i don't think there's a need to, and i think it's more like because you are not using other tools like haml to help reduce the number of lines in an erb files
the same code can be achieved in haml in just 1 line:
#left-nav= render :partial => 'tests/tests_left_menu'
hope this helps =)
I suppose if you have that code in many places I'd move the the div into the partial. If you need the flexibility to have tests_left_menu outside of the div I'd still pick two partials over a helper in this scenario. Avoid writing html in Ruby when you can :)

Branching logic in an MVC view

I find myself writing a lot of code in my views that looks like the code below. In this case, I want to add some explanatory HTML for a novice, and different HTML for an expert user.
<% if (ViewData["novice"] != null ) { %>
some extra HTML for a novice
<% } else { %>
some HTML for an expert
<% } %>
This is presentation logic, so it makes sense that it is in a view vs the controller. However, it gets ugly really fast, especially when ReSharper wants to move all the braces around to make it even uglier (is there a way to turn that off for views?).
My question is whether this is proper, or should I branch in the controller to two separate views? If I do two views, I will have a lot of duplicated HTML to maintain.
Or should I do two separate views with a shared partial view of the stuff that is in common?
Ideally, this kind of logic would be handled in the view model and the view should just be rendering the model.
So you might have something like in your view:
<%= ViewData["helptext"] %>
and your logic in the controller would be something like:
ViewData["helpText"] = isNovice ? noviceText : expertText;
that way you can push that logic back to the controller and keep your views nice and clean
You're trying to create 2 completely separate html pages with identical models. You want a separate view. Don't try to out clever the design pattern with conditional-branching logic.
HTML helpers aren't going to help you much here, since it appears you will not be repeating much logic other than if else.

In Rails, is there a way to selectively load files in the view from application layout?

So in my Rails application, I'm trying to set up Javascript testing on certain views.
Right now, I'm doing this by having a conditional in each view..
<% if AppConfig['js_testing'] %>
<script>
...
</script>
<% end %>
If I have it on each page, there's a lot of code duplication. Is there a way manage everything from the application layout?
There's a few places you can put this that will help reduce duplication. The main layout is an ideal candidate. Another possibility is a helper method that's a lot easier to introduce.
You could also define a conditional javascript_tag helper method that will only introduce the JavaScript if your trigger is set. Usually this is along the lines of:
def javascript_testing_tag(content)
AppConfig['js_testing'] ? javascript_tag(content) : ''
end
Then it's a pretty straightforward exercise to wrap all your test scripts with that conditional. It will make it easier to refactor things later should the logical trigger for this behavior change.
The optimal implementation depends on what kind of scripting content you're introducing. If it's tied closely to the JavaScript that may be on a particular view, you may be stuck doing this.
An alternative is to simply tag each page and have a testing JavaScript harness that will trigger specific behavior depending on the structure of the document. For example, if there's an element div#user_list you might run testUserList().
It is then trivial to simply not include the testing JavaScript file in non-testing environments.

Correct coding convention for embedded code on web page templates

I had come experience with PHP a time ago and now I'm learning to use Ruby on Rails. But one simple question bothered me in both these languages, so I think I can cross-post it to both tags.
As you know, one of the concepts there is that one can embed PHP or Ruby code into web page template. Then these statements are executed and result of its execution is inserted in certain places of the page, marked with "brackets" <%= ... %>.
Or... wait. We program Ruby/PHP, but not HTML. Maybe we should treat template as Ruby/PHP code, into which sometimes HTML markup is inserted? So the process is treated like that HTML are inserted into ruby code into the "brackets" %> ... <%.
These are two different approaches:
HTML page is the primary entity, and it is affected by code execution; or
code is the primary entity, and it is executed, while HTML snippets are inserted in certain places.
This philosophy leads to different possibilities in coding conventions: result of code execution influences the page If we adhere the first insight, then the code would look like this:
<p>
<% (1..10).foreach do |i| %>
Iteration number <strong><%= i %></strong>. <br/>
<% end %>
</p>
But if we stick to the second alternative, the code would be formatted like this:
<%
%><p><%
(1..10).foreach do |i|
%>Iteration number <strong><%
%><%= i %><%
%></strong>. <br/><%
end
%>
How should the concept of templates be construed? What concepts do you, way more experienced Web developers, account for the coding convention?
If this is in your View layer (and it should be), then the HTML is the primary entity. It's the most pertinent part of that layer -- marking up your data to display in meaningful ways to the user.
Even aside from that, your second example is nearly unreadable. I see what you're doing, but it took me a minute to wrap my brain around it. I've also never, ever seen View-layer code like your second example (and I would make it one of my priorities to change it wherever I saw it if it was in a project I was working on).
To be more concise: you're putting the emphasis on the wrong thing. In my opinion, readability trumps just about everything else. The coding style that produces the most readable code is therefore the most superior (ceteris paribus and YMMV, of course).
Maybe you should look into Haml? I don't know if there's a php equivalent, but as far as Rails goes, it's somewhere in between the two schemes. It's not quite code centric. But when used right, all the raw html is prepared programatically.
In short everything is considered text to be directly outputted, unless prefixed with either a %, - or =. Which translate to html-tag, ruby code that doesn't output. Ruby code that does output. Haml then uses whitespacing to nest things properly, much like python does. Raw html outputs untouched but using % to specify a tag handles closing tags.
Sample:
#outer-div
- #items.each do |i|
%span.item
= i
%br
Outputs
<div id="outer-div">
<span class="item">
item
</span>
<br>
</div>
See the haml tutorial for more information.
To answer the central question. The bulk of any page is going to be HTML or raw text. We reduce the bulk of that text with includes and helpers, but it's still there. If there were a truly code centered approach my use of it would depend on the ratio of program logic to html. Personally I'd rather go with the html centered approach.
If you are interested in a code-oriented view, this is something you might try implementing as a pure Ruby DSL:
tag :p, :class => 'iterations-container' do
(1..10).each do |i|
text "Iteration number "
tag :strong { text i }
text "."
tag :br
end
end
Or perhaps instead of tag :p do ... end, you may favor tag.p do ... end.
I recommend doing only very simple logic in your template files. That way designers who can edit HTML can easily edit even those files to alter the layout if need be.

Resources