A gem for every occasion: 11 great Rails libraries we use on every project

Published in Tools, Ruby, Ruby on Rails developmentComments

As you work with your favorite programming language, you often look for tools to make your job easier. In the Ruby world, these tools (gems) are created on a daily basis, but only some of them are good enough to win our hearts.

Here are some of the core gems that have a special place in all of our Gemfiles. Some of them help with debugging code, others provide certain functionality like authentication. That's useful in almost any project. In the end, they all help us work faster and produce quality software.

title

1. better_errors

Standard Rails error page offers valuable information, but it's static, so you can't check what actually went wrong - besides the stack trace. Better Errors, in combination with binding_of_caller, allows you to inspect source code live through a console that works on every stack frame. Rails 4.2 added something similar, but we've yet to see if it will manage to replace Better Errors. better\_errors

2. devise

Whether you need simple HTTP authentication, or you're looking for some complex Facebook and Google+ login system, this authentication solution is great and it will significantly speed up your work. It's built on top of the Rails MVC stack and its modular architecture allows you to pick what you need.

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable, :confirmable, :recoverable, stretches: 20
end

3. cancancan

The successor of the abandoned cancan project, this authorization gem lets you define what a user can do on your website by using abilities defined in a single place.

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    if user.admin?
      can :manage, :all
    else
      can :read, :all
    end
  end
end

In newer projects we started experimenting with pundit. It is faster, more modular and it wont bloat a single file.

4. delayed_job

We find this gem to be the best when you need to extract some longer-running actions (e.g., sending newsletters to a large number of users) into a background task. You can reuse methods from your models, or you can create complex classes for all your background task needs. With delayed_job, even progress bars are possible in Ruby on Rails.

# without delayed_job
Notifier.signup(@user).deliver

# with delayed_job
Notifier.delay.signup(@user)

# with delayed_job running at a specific time
Notifier.delay(run_at: 5.minutes.from_now).signup(@user)

5. letter_opener

It's quite annoying to set up email delivery in a development environment, and that's where Letter Opener is great. It displays the email in your browser so you can easily inspect it, click any links (e.g., account confirmation) and not spam your email account with tons of test emails.

letter\_opnener demo

6. mina

Easily configured, this gem allows you to do fast remote deployments of you website, as multiple environments are supported and all the work is done in only one SSH session (compared to Capistrano's multiple SSH sessions). For more info, check out this article about Mina, written by my colleague Gabrijel Škoro.

➜  project git:(master) ✗ mina production deploy
-----> Creating a temporary build path        
-----> Fetching new git commits        
-----> Using git branch 'master'        
       Cloning into '.'... 
       done. 
-----> Using this git commit        

       user (0695b54): 
       > increase credits after manual order update 

-----> Symlinking shared paths        
-----> Installing gem dependencies using Bundler        
       # list of gems ommited
       Your bundle is complete! 
       Gems in the groups development and test were not installed. 
       It was installed into ./vendor/bundle 
-----> DB schema unchanged; skipping DB migration        
-----> Skipping asset precompilation        
-----> Cleaning up old releases (keeping 5)        
-----> Build finished        
-----> Moving build to releases/307        
-----> Updating the current symlink        
-----> Launching        
-----> Symlink system to shared        
-----> Restarting application        
-----> Done. Deployed v307        
       Elapsed time: 2.00 seconds

7. paperclip

You often have to deal with attachments that need to be processed in various ways. With paperclip, that becomes quite simple (with the support of ImageMagick) and allows you all sorts of validations and transformations, providing support for customizations as well.

class User < ActiveRecord::Base
  has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
  validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end

If you feel adventurous, you can try refile from the creators of carrierwave.

8. simple_form

Plain Rails generated forms (and related helpers) aren't really that helpful when you're designing a great user interface, which is essential for every website. This is where Simple Form saves the day with its powerful yet simple DSL.

= simple_form_for @user do |f|
  = f.input :username, label: 'Your username please'
  = f.input :password, hint: 'No special characters.'
  = f.input :email, placeholder: 'user@domain.com'
  = f.input :remember_me, inline_label: 'Yes, remember me'
  = f.button :submit

9. rspec-rails

If you're doing testing (and you should!), this gem helps you to easily integrate rspec framework into your Rails project by generating the necessary configuration files and spec helpers.

require "spec_helper"

describe User do
  it "orders by last name" do
    lindeman = User.create!(first_name: "Andy", last_name: "Lindeman")
    chelimsky = User.create!(first_name: "David", last_name: "Chelimsky")

    expect(User.ordered_by_last_name).to eq([chelimsky, lindeman])
  end
end

10. factory_girl_rails

When testing your projects, you need data. The best way to generate test data is to use a factory generator. The factory_girl_rails gem helps you to easily integrate Factory Girl, our favorite factory generator, into your Rails projects.

# spec/factories/user.rb
FactoryGirl.define do
  factory :user do
    first_name "Andy"
    last_name  "Lindeman"
  end
end

# spec/models/user_spec.rb
require "spec_helper"

describe User do
  it "orders by last name" do
    lindeman = create(:user)
    chelimsky = create(:user, first_name: "David", last_name: "Chelimsky")

    expect(User.ordered_by_last_name).to eq([chelimsky, lindeman])
  end
end

11. pry-rails

Debug your code like a champ. With pry, you can see what went wrong in any part of your Rails project, in your tests, third-party gems, and it can even be used in the Rails console.

Started GET "/" for 127.0.0.1 at 2014-10-24 09:57:12 +0200
Processing by HomeController#index as HTML
  User Load (0.5ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 1  ORDER BY "users"."id" ASC LIMIT 1

From: /Users/stef/dev/gluposti/blogs/app/controllers/home_controller.rb @ line 4 HomeController#index:

    2: def index
    3:   @user = current_user
 => 4:   binding.pry
    5: end

[1] pry(#<HomeController>)> current_user
=> #<User id: 1, email: "admin@infinum.co", encrypted_password: "$2a$10$AR/1ZnYJS5hqFNtDzx3ZGuGlRlinktNPebsp6Ye5ENn...", reset_password_token: "5e116a7fd356c11cccfcf27ab981e19b5a756dd7c6f2bd64ba...", reset_password_sent_at: "2014-10-24 07:32:34", remember_created_at: nil, sign_in_count: 2, current_sign_in_at: "2014-10-24 07:57:12", last_sign_in_at: "2014-10-24 07:25:25", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", created_at: "2014-10-24 07:25:25", updated_at: "2014-10-24 07:57:12">
[2] pry(#<HomeController>)> cd @user
[3] pry(#<User>):1> email
=> "admin@infinum.co"
Did you like this?
If you liked this article, subscribe to our newsletter and get more content like this
Share your thoughts
Greetings from our lovely team!
1/4
Achievement unlocked
Resize Master