31

I'm using Ruby on Rails and need to run a block of Ruby code in one of my html.erb files. Do I do it like this:

<% def name %>
<% name = username %>
<%= name %>

or like this:

<% def name
name = username %>
<%= name %>

Thanks for reading.

the12
  • 2,395
  • 5
  • 19
  • 37
ben
  • 29,229
  • 42
  • 124
  • 179
  • Why are you trying to create a function in a view? It belongs most likely into the model, or if not into the controller, but definitely not into the view – jigfox Jun 23 '10 at 08:21
  • Sorry, I just quickly typed some code in there as an example. – ben Jun 23 '10 at 08:39

3 Answers3

42

If you need extra functions in your view, you normally declare those inside a helper.

For each controller, if there is a helper it is automatically loaded. For instance, if you have a PeopleController, in the app/helpers folder, there should be a people_helper.rb, and it should look like this

module PeopleHelper
  def name
    #do something
    username
  end
end

Another, very clean alternative, is to use the Presenter pattern, but i think it is less common (unfortunately).

Otherwise, if you do need multiple lines of ruby code inside a erb view, which i try to avoid, i prefer the following style:

<%
   counter_1 = 0
   counter_2 = 1
   do_some_more_prep_here
 %>
<% @records.each do |rec|%>
  <%# do something with the prepped date in each row %>
<% end %>

Also for me code indentation is more important than html indentation, so i will prefer something like

<table> 
  <% @rows.each do |row| %>
    <tr>
      <td><%= row.item1 %></td>
      <% if row.some_test %>
        <td><%= row.item2 %></td>
      <% end %>
    </tr>
  <% end %>
</table>

But i am always very interested to hear different opinions in this matter.

nathanvda
  • 49,707
  • 13
  • 117
  • 139
  • 4
    Helper methods are the way to go, for sure. – tadman Jun 23 '10 at 14:22
  • How would you go about using the PeopleHelper name method in the html.erb? – CyberMew Jun 29 '18 at 08:32
  • Any method declared in a helper should just be available in the views (so with that in mind I would prefer a bit more specific method-name now, looking back). Is that not the case for you? – nathanvda Jun 29 '18 at 10:16
25

It is unusual to define a method in an ERB file, so I recommend against it.

If you want to call a block like #each, you can do something like the following:

<% names.each do |name| %>
  <%= name %>
<% end %>

Don't forget the <% end %>.

user456584
  • 86,427
  • 15
  • 75
  • 107
shingara
  • 46,608
  • 11
  • 99
  • 105
-1

I can imagine someone needing it in one particular template (no point in creating a helper) to not duplicate html markup. That is, when resulting html page has a couple of similar blocks of html markup. Though, it can easily be abused (unreadable code).

<% def f1(a, b, c) %>
  test: <%= a %>, <%= b %>, <%= c %>
<% end %>

<% f1(1, 2, 3) %>
<% f1(4, 5, 6) %>
x-yuri
  • 16,722
  • 15
  • 114
  • 161
  • your answer doesn't work, all it is doing is putting the contents of the function on a webpage, treating it as HTML not as rails or ruby code https://i.imgur.com/rhTNtt5.png – barlop Feb 20 '18 at 14:55
  • @barlop Sorry for being unelaborate. Check out my answer. Does that work for you? That's probably what I meant. – x-yuri Feb 20 '18 at 17:18
  • that displays `test: ,,,` because your code has `<%` and not `<%=` But this works https://i.imgur.com/Gtytbg9.png So you might want to correct your answer and you should really have tested it before posting it. – barlop Feb 20 '18 at 17:40
  • @barlop I'm not sure where I get that idea. But I assure you I tested it. Maybe it worked with the other version of Rails or `erb` gem. The problem is that I wasn't elaborate enough. Does my current solution work for you? – x-yuri Feb 20 '18 at 18:15