3

I'm trying to create a helper method that can have optional arguments for link_to method. My intention is to create a helper method for different cases:

# Typical case #1 (can have any number of extra arguments)
<%= toolbar_item('google.com', 'Google', 'globe', 'btn-primary', target: '_blank') %>

# Typical case #2 (extra arguments are optional)
<%= toolbar_item(root_path, 'Start', 'flag', 'btn-primary') %>

Follows the code:

def toolbar_item(url,text,icon,custom_class, optional_extra_settings = {})
  link_to raw("<i class='fa fa-#{icon}'></i> #{text}"), url, class: custom_class, optional_extra_settings
end

It's no good. link_to method does not recognize the extra_settings and raises and error.

Any ideas? Thanks!

Fernando
  • 325
  • 2
  • 13

2 Answers2

4

The link_to method accepts only 3 arguments. The last argument needs to be a hash. Therefore you have to merge your class setting with the optional extra settings hash.

Change your example to:

def toolbar_item(url, text, icon, custom_class, optional_extra_settings = {})
  html_options = { class: custom_class }.merge(optional_extra_settings)
  link_to raw("<i class='fa fa-#{h icon}'></i> #{h text}"), url, html_options
end

Furthermore, you will notice that I used h to escape your icon and text. Just to be safe, because you disabled the auto-escaping that is usually done by Rails by using raw.

spickermann
  • 100,941
  • 9
  • 101
  • 131
1

Don't reinvent the wheel. The CSS class is an option you can pass to the link_to helper via the options hash. Let's move it to the options hash and remove one needless argument.

# notice class: 'btn-primary' vs 'btn-primary'
<%= toolbar_item(..., class: 'btn-primary', target: '_blank') %>

Now, link_to also accepts a block. Use it to simplify your code pass the icon ('globe' or 'flag', etc...) as a block.

def toolbar_item(url, text, options = {}, &block)
  if block_given?
    link_to url, options do
      yield
    end
  else
    link_to text, url, options
  end
end

Now, each time you use the helper with an icon, you can specify the icon you want:

<%= toolbar_item 'google.com', class: 'btn-primary' do %>
  <%= content_tag :i, class: 'globe' %> Google
<% end %>

Which begs the question. Do you really need a helper after all? All we did was create a wrapper. You can just do:

<%= link_to 'Google', 'google.com', class: 'btn-primary' %>

<%= link_to 'Google', class: 'btn-primary' do %>
  <%= content_tag :i, class: 'globe' %> Google
<% end %>
Mohamad
  • 34,731
  • 32
  • 140
  • 219
  • it worked nice too! As you guys explained, I was getting wrong the options hash for the original link_to method, but now It's clear. Answering your question, if I really need this method: yes, i do, so I can change style and properties for the toolbar itens in whole app in just one place. – Fernando Feb 20 '16 at 14:10