DEV Community

loading...
Cover image for How to render conditionals to action view with application helpers in Ruby on Rails

How to render conditionals to action view with application helpers in Ruby on Rails

AshakaE
Full Stack developer, Rails enthusiast, part-time guitarist. Stack: JavaScript, Ruby, Rails, React, Redux.
・2 min read

PROBLEM: Writing if-else statements in your rails action view template does not look good or professional. You can use partials but they are still html.erb which still is an action view. Take a look at the code below;

menu.html.erb
   <% if controller_name == 'groups' && action_name == 'show' %>
          <p class="font-bold mr-3 text-md"> <small class="font-medium mr-1">created by </small> <%= project.user.name %></p>
   <% end %>
Enter fullscreen mode Exit fullscreen mode
 <% 1.upto(20) do |i| %>
    <li class="p-4 m-1">
     <%= f.radio_button :icon, @icons[i]['link'], class: "focus:ring-secondary h-4 w-4 text-secondary border-gray-300" %>
     <%= f.label :icon, value: @icons[i]['link'], class: "w-2 h-2 py-4" do %>
      <img src="<%= @icons[i]['link']%>" alt="" class="w-14 h-14">
       <% end %>
    </li>
  <% end %>
Enter fullscreen mode Exit fullscreen mode

and

_partial.html.erb
   <% if logged_in? %>
        <a href="/users/<%= current_user.id %>">
   <% else %>
        <a href="/">
   <% end %>
Enter fullscreen mode Exit fullscreen mode

A much cleaner solution would be to use the helper methods inside application_helper.rb to render these conditionals.

Inside the helper file, create a method, set an empty string to a variable, and write your conditional statement like you would write it in ruby. Remove the erb tags and wrap HTML code in strings. Now push the string with your code into the variable and set it to variable.html_safe. example;

application_helper.rb
   def show_proj_name(project)
    content = ''
    if controller_name == 'groups' && action_name == 'show'
      content << "<p class='font-bold mr-3 text-md'>
                  <small class='font-medium mr-1'>
                  created by </small>  #{project.user.name} </p>"
    end
    content.html_safe
  end

  def show_icons(ico)
    content = ''
    1.upto(20) do |i|
      content << "<li class='p-4 m-1'>
                  #{ico.radio_button :icon, @icons[i]['link'], class: 'focus:ring-secondary h-4 w-4 text-secondary border-gray-300'}"
      content << "#{ico.label :icon, value: @icons[i]['link'], class: 'w-2 h-2 py-4' do
                    image_tag(@icons[i]['link'], class: 'w-14 h-14')
                  end}"
      content << '</li>'
    end
    content.html_safe
  end
end

def navlink(*)
    content = ''
    content << if logged_in?
                 "<a href='/users/ #{current_user.id}'>"
               else
                 "<a href='/'>"
               end
    content.html_safe
  end

Enter fullscreen mode Exit fullscreen mode

Because they're functions that need to be run, you call them directly in the action view with the erb tags that executes ruby code <%= %>. see the finished result;

menu.html.erb
   <%= show_proj_name(project) %>
Enter fullscreen mode Exit fullscreen mode


N.B. f is passed as an argument because, in the action view, the form was built with that variable.

   <%= show_icons(f) %>
Enter fullscreen mode Exit fullscreen mode
_partial.erb
   <%= navlink(logged_in?)  %>
Enter fullscreen mode Exit fullscreen mode

Conclusion
You can now see less bulky and much cleaner code in your action views and, focus on writing more HTML code.

Thanks for reading.

Discussion (0)