If else statements in .html.erb in views

Ruby on-RailsRubyModel View-Controller

Ruby on-Rails Problem Overview


In rails, I often run into the situation where inside the views I'll do something like

<% if @some_condition_previusly_established_in_a_controller %>
 <div class="one">123</div>
<% else %>
 <div class="two">something else</div>
<% end %>

It looks a bit cluttery. Is this an acceptable way of working with views or not?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

Unless you can think of a way to re-write this as a helper method, you're basically stuck with it looking kind of ugly. That's just how ERB is, as it was intended to be a minimal way of injecting Ruby into an otherwise plain-text template, not as something necessarily streamlined or elegant.

The good news is a syntax-highlighting editor will usually make your <% ... %> ERB blocks look visually different from your HTML so that can dramatically improve readability.

It's also why other representations like HAML have been created where that syntax is a lot less cluttered:

- if some_condition_previusly_established_in_a_controller
  .one 123
- else
  .two something else

Solution 2 - Ruby on-Rails

For one or two such conditional logic in your views, I guess its fine but when your code gets bigger and you have multiple if..else..end and looks "cluttery", I think you should look at implementing "Presenter Pattern" which greatly cleans up your views by separating your logic to Presenters.

Here is a great tutorial I followed from Ryan Bates in his Rails Casts series on "Presenter Patterns from scratch". http://railscasts.com/episodes/287-presenters-from-scratch.

Solution 3 - Ruby on-Rails

Have you tried?

<% @some_condition_previusly_established_in_a_controller ? <div class="one">123</div> : <div class="two">something else</div> %>

Solution 4 - Ruby on-Rails

If your view contains lots of tags and HTML elements, you can put them into partials and logic into model

View:

<%= render :partial => @model.status %>

<%= render :partial => "file/path/#{@model.status}" %> # if your partial is in some different folder

If your status is one, then it would render the file _one.html.erb

If it is two, then it would render the file _two.html.erb automatically.

Model:

def status
	if @some_condition
	  "one"
	else
	  "two"
	end
end

Solution 5 - Ruby on-Rails

Yes, that is the standard (and yes, it looks cluttery).

If you're looking for a possibly cleaner alternative, check out: https://stackoverflow.com/questions/5809917/conditional-tag-wrapping-in-rails-erb

Solution 6 - Ruby on-Rails

You can always move the logic to the controller and leave the view clean(er).

Controller:

if @some_condition
  @div_class = :one
  @div_content = 123
else
  @div_class = :two
  @div_content = 'something else'
end

View:

 <div class="<%= @div_class %>"><%= @div_content %></div>

Or using a helper:

 <%= content_tag :div, @div_content, class: @div_class %>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questiondsp_099View Question on Stackoverflow
Solution 1 - Ruby on-RailstadmanView Answer on Stackoverflow
Solution 2 - Ruby on-RailsveeView Answer on Stackoverflow
Solution 3 - Ruby on-RailsajthewebdevView Answer on Stackoverflow
Solution 4 - Ruby on-RailsSundaView Answer on Stackoverflow
Solution 5 - Ruby on-RailsRebitzeleView Answer on Stackoverflow
Solution 6 - Ruby on-Railsuser4299424View Answer on Stackoverflow