Rails Helper Methods

When I had started developing in Rails it was months before I even heard of “Helper Methods”. I did see the folder in the app directory, but I didn’t see any use for it at the time. I mean Rails is pretty much Model-View-Controller, so why would anyone need helper methods?

Well once I found an example online of a helper method it just clicked. A helper method is a method written for the view, it’s designed to be reusable anywhere within the website, and it cleans up the view code by separating out some logic.

For example, I currently use Cloudinary for image hosting services. Cloudinary has its own methods for displaying images within a website. It is possible that I may one day want to change and not use Cloudinary any more. So I wrote some helper methods that will call either Cloudinary’s image helper, or the standard image helper tag depending on if Cloudinary is defined:

/app/helpers/image_helper.rb # /app/helpers/image_helper.rb module ImageHelper def ex_image_tag(*arguments, **keyword_arguments, &block) if defined? Cloudinary cl_image_tag(*arguments, **keyword_arguments, &block) else image_tag(*arguments, **keyword_arguments, &block) end end def ex_image_path(*arguments, **keyword_arguments, &block) if defined? Cloudinary cl_image_path(*arguments, **keyword_arguments, &block) else image_path(*arguments, **keyword_arguments, &block) end end end 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # /app/helpers/image_helper.rb module ImageHelper def ex_image_tag ( * arguments , * * keyword_arguments , &block ) if defined ? Cloudinary cl_image_tag ( * arguments , * * keyword_arguments , &block ) else image_tag ( * arguments , * * keyword_arguments , &block ) end end def ex_image_path ( * arguments , * * keyword_arguments , &block ) if defined ? Cloudinary cl_image_path ( * arguments , * * keyword_arguments , &block ) else image_path ( * arguments , * * keyword_arguments , &block ) end end end

Now anywhere in my view I use ex_image_url and ex_image_path as my image helpers. So in theory the code may work without much, if any, change when change is needed.

Just today I wrote a helper method for Gravatar images. Gravatar is basically a Global Avatar per email address. Many websites have Gravatar integrated so that when you use your email address on their site you automatically have a profile image associated with it. It’s one central place to keep your professional image. Here’s my helper method:

/app/helpers/image_helper.rb # /app/helpers/image_helper.rb module ImageHelper def gravatar(email, size, border) "<img src=\"http://www.gravatar.com/avatar/#{ Digest::MD5.new.update( email.to_s.strip.downcase ).hexdigest }?d=blank&s=#{size}&r=g\" style=\"height:#{size}px;width:#{size}px;border:#{border}px\">".html_safe end end 1 2 3 4 5 6 7 8 9 10 11 12 13 # /app/helpers/image_helper.rb module ImageHelper def gravatar ( email , size , border ) "<img src=\"http://www.gravatar.com/avatar/#{ Digest::MD5.new.update( email.to_s.strip.downcase ).hexdigest }?d=blank&s=#{size}&r=g\" style=\"height:#{size}px;width:#{size}px;border:#{border}px\">" . html _ safe end end

For more details on how to modify this method for your own usage see my Coderwall Pro-Tip “Rails Gravatar Helper Method“.

Calling a helper method in your view is straight forward. For an example of using my Gravatar code in the view I could do the following:

/app/views/profile/show.html.erb Profile Picture:<br /> <%= gravatar(profile.email, 72, 3) %> 1 2 3 Profile Picture : <br /> <%= gravatar ( profile . email , 72 , 3 ) %>

In the example above the helper method gravatar is called and renders out html in place in the view. The example gets the email from the profile Object in the view with profile.email. So now you have a Gravatar profile image as easy as that thanks to helper methods!

Now there are times when you want to use your helper methods in your Controllers but you will find that the helper methods aren’t available within the scope of the Controllers. There are a few techniques available on this StackOverflow answer “Rails – How to use a Helper Inside a Controller“.

One answer that’s not given on any StackOverflow answer that I can see is to write the methods in the Controller rather than the Helper. Consider where you will need to use the method. If you need to use it in both the controller and the view then write it in the controller. Then use the wonderful method named helper_method.

/app/controllers/application_controller.rb # /app/controllers/application_controller.rb class ApplicationController < ActionController::Base def notification_count current_user.emails.count + current_user.friend_requests.count + current_user.close_friends.updates.count end helper_method :notification_count end 1 2 3 4 5 6 7 8 9 10 11 12 # /app/controllers/application_controller.rb class ApplicationController < ActionController :: Base def notification _ count current_user . emails . count + current_user . friend_requests . count + current_user . close_friends . updates . count end helper_method : notification _ count end

Now please don’t be too hasty to place “everything” in the application controller. The application controller will end up becoming way too cluttered and bloated if you do. But if you “need” to have access to a method in both the controllers and the views then this is a good place for you; helper_method has your back. It’s simple, beautiful, and convenient.

Now with more experience comes more wisdom. In my last code example you’ll notice I’ve called count on several different queries from the DB all relating to the current_user. You could call this a code smell. Honestly I wrote this method just for an example of using helper_method within your controller. But when using query logic like this for your User then you should move this to a Model method. You can’t call current_user from within models since it’s out of scope so you will need to change the code up a bit.

/app/models/user.rb # /app/models/user.rb class User < ActiveRecord::Base def notification_count self.emails.count + self.friend_requests.count + self.close_friends.updates.count end end 1 2 3 4 5 6 7 8 9 10 11 # /app/models/user.rb class User < ActiveRecord :: Base def notification _ count self . emails . count + self . friend_requests . count + self . close_friends . updates . count end end

Now the method notification_count is a Class/Object instance method of User. current_user is an instance of User so you can call current_user.notification_count and it will refer to all the related objects to self, a.k.a. current_user instance. You can use this in both the view and your controllers now with current_user. (current_user is a method available with the devise gem/library)

So database model specific things should be in your models files, other than that helper methods are there to “help” you with you view. And if any specific need should arise you can have your helper methods defined within controllers with helper_method. It’s good practice to separate logic out of your view when you can. It’s the pattern of “Separation of Concerns”. What concerns the model, belongs with the model. And the same is true for the rest of your project.

As always I hope you found this both an enjoyable and an insightful read. Please comment, share, subscribe to my RSS Feed, and follow me on twitter @6ftdan!

God Bless!

-Daniel P. Clark

Image by Brooke Novak via the Creative Commons Attribution-NonCommercial-NoDerivs 2.0 Generic License.