53

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?

dsp_099
  • 5,801
  • 17
  • 72
  • 128

6 Answers6

28

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
tadman
  • 208,517
  • 23
  • 234
  • 262
  • 3
    That sort of stuff is why I prefer HAML over ERB. HAML gets rid of the clutter. – the Tin Man Jul 22 '13 at 18:50
  • I have a problem with HAML (I use slim). HAML syntax is clear and concise when your html code is short. but it will become messy when code is large. You also cannot format code when using some IDE or plugins .... – hqt Oct 26 '17 at 16:27
  • @hqt HAML is pretty good until your inline bits of code get too huge, it's true, but you can usually mitigate that by writing helper functions that minimize how much code you have in your template. As you point out there are other HAML-like meta-HTML notation systems as well, so if you're unhappy with ERB you do have options. – tadman Oct 26 '17 at 16:30
10

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.

vee
  • 38,255
  • 7
  • 74
  • 78
  • Nice link but not viewable to those of us without a paid account. =( – Charles Caldwell Jul 22 '13 at 18:57
  • Yes, I'm just concerned if I will be violating the copyright laws if I posted the github source link, I'll try to post a link to the source and edit my answer to include the necessary classes and files to look at if it doesn't chase me :) – vee Jul 22 '13 at 19:00
  • It looks like [episode 287](https://github.com/ryanb/railscasts-episodes/tree/master/episode-287) is public in at least one of his repos. – Charles Caldwell Jul 22 '13 at 19:04
  • @CharlesCaldwell, yes the link you provided does contain the implementation of Presenter Pattern. The files you want to be looking for are in the `app/presenters/`, `app/helpers/application_helper.rb` and one of the usage of the same can be found in `app/views/users/show.html.erb`. Have a look at them in `profile-after`. – vee Jul 22 '13 at 19:08
8

Have you tried?

<% @some_condition_previusly_established_in_a_controller ? <div class="one">123</div> : <div class="two">something else</div> %>
ajthewebdev
  • 432
  • 2
  • 5
  • 17
6

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
Sunda
  • 227
  • 3
  • 3
2

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

If you're looking for a possibly cleaner alternative, check out: Conditional tag wrapping in Rails / ERB

Community
  • 1
  • 1
Rebitzele
  • 3,252
  • 1
  • 20
  • 21
-3

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 %>