Ruby on Rails: Top 10 Gems

After developing a number of Rails 3 apps, I’ve come to build up a list of “prerequisite” gems that I must install before I decide to include anything else.

Without further ado, here are my top 10 must have gems for RESTful, DRY development.

simple_form

Let’s face it: as awesome as Rails is, form building is not exactly its forte. That’s why I recommend simple_form, a gem that makes form partials a breeze to customize, generate, and understand. With support for native I18n, inline validations, nested models, extensive options, and unbeatable customization, simple_form is a serious deal for forms.

With some bundle magic, turn your forms:

<%= form_for @post, :html => { :multipart => true } do |f| %>
<p>
  <%= f.label "category_id", "Category" %>
  <%= f.select("category_id", Category.all.collect {|p| [ p.name, p.id ] }, { :include_blank => true }) %>
</p>
<p>
  <%= f.label "date", "Date" %>
  <%= f.date_select "date" %>
</p>
<p>
  <%= f.label "title", "Title" %>
  <%= f.text_field "title" %>
</p>
<p>
  <%= f.label "photo", "Upload a photo" %>
  <%= f.file_field "photo" %>
</p>
<% end %>

Into a creative outlet.

<%= simple_form_for @post, :html => { :multipart => true } do |f| %>
  <%= f.association :category, :include_blank => true %>
  <%= f.input :date, :as => :date %>
  <%= f.input :title %>
  <%= f.input :photo, :label => "Upload a photo" %>
<% end %>

paperclip

Dead simple file attachments. Seriously easy. Next to simple_form, this is literally the second installed gem in all of my apps. If you are using any other attachment gem, you’re old school — paperclip is pure joy in clean, DRY code haven.

# /models/post.rb
class Post < ActiveRecord::Base
  has_attached_file :photo
  ...
end

# /views/posts/show.html.erb
<%= image_tag @post.photo.url if @post.photo? %>

jquery-rails

When I first started rails, my only complaint was the prototype library integration…to me, prototype is unintuitive, bloated, and too nitty-gritty. When Rails 3 shipped out with a resounding move towards framework independence, I was only too happy to accommodate the gap with jQuery. But it was a pain to install, and none of the remote options worked unless I were to write up my own scripts.

Thanks to jquery-rails, the power of jQuery is united with Rails (an excellent combo!) with a simple generator command. Just add the gem to your gemfile, bundle install, and run rails g jquery:install or pass the -j jquery option when you are creating a new app.

kaminari

When it came time to find a pagination gem for posts, I naturally checked out will_paginate. However, either because of the gem’s age or name, it wasn’t exactly my dream pagination gem — that’s when I came across kaminari, a modern Rails 3 only gem with a simple interface and excellent customizability. In addition to being natively built for Rails 3, kaminari also takes advantage of the new Rails queries by making the page method accessible via a scope relation. Customize the text with I18n, restyle the page selector template, and continue to take full advantage of ActiveRecord Relations.

# /app/models/post.rb
class Post < ActiveRecord::Base
  paginates_per 5
  ...
end

# /app/controllers/posts_controller.rb
class PostsController < ApplicationController
  @posts = Post.published.page params[:page]
  ...
end

# /app/views/posts/index.html.erb
<%= paginate @posts %>

nokogiri

Slick HTML parsing — these descriptors are normally exclusive outside the webkit render engine, but Ruby is the exception thanks to nokogiri, which unites the power of jQuery DOM traversing with a standards built HTML/XML core. This powerful plugin powers my HTML truncation method, which you can check out at Ruby Extension: HTML Truncation.

high_voltage

Rails is great for a web app, but more than once I’ve needed to build a “semistatic” page — like an about me page that still needs the application layout, view helpers, and maybe very limited database access, but then again building an entire controller for it makes no sense since it is not a resource or database backed.

Enter high_voltage, made by the same guys who developed Paperclip (#2 on the list!). With it, you can get RESTful static pages that won’t leave you in programmer’s depression. This gem turns those nasty static pages into their own “resources” so you can give even your “about me” page that Rails sparkle.

cancan

Authentication…one of those topics that causes the typical Rails developer to squirm and whine. Well, that was before cancan; I’m quite impressed by how well Ryan Bates was able to separate such a central part of a web app into a virtually “no strings attached” gem. CanCan is a wonderfully minimalistic solution to managing resource access, without all the customization and security headaches typically encountered with other intrusive security gems.

# /app/models/ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)

    can :read, :all
    can :manage, User, :id => user.id

    can :read, Post, :status => "Active"
    can :manage, Post, :user => { :id => user.id }
  end
end

# /app/controllers/posts_controller.rb
class ResumesController < ApplicationController
  # Tell CanCan that this is a protected resource, and needs to be loaded through the author
  load_and_authorize_resource :user, :find_by => :handle
  load_and_authorize_resource :resume, :through => :user, :shallow => true
end
# /app/index/posts/show.html.erb
<% if can? :create, @user.posts.build then %>
  <%= link_to "Create a new post", new_user_post_path(@user) %>
<% end %>

<% unless cannot? :edit, @post then %>
  <%= link_to "Edit this post", edit_user_post_path(@user, @post) %>
<% end %>

bcrypt-ruby

Of course, if you’re going to be handling authentication in your app, it might be useful to have a hash library handy. Perhaps the most popular gem out there for cryption related methods is the bcrypt-ruby implementation. The interface is reasonably easy to use, but since I mostly use this library for really basic secure password hashing, I haven’t used its more interesting capabilities.

require 'bcrypt'

class User < ActiveRecord::Base
  include BCrypt

  # Returns hashed password
  def password
    @password ||= (Password.new(password_hash) unless password_hash.blank?)
  end

  # Hashes password and records it in the database
  def password=(new_password)
    @password = Password.create(new_password)
    self.password_hash = @password
  end
end

mechanize

Sometimes websites don’t provide an HTTP accessible API (why they wouldn’t set aside several business days worth of billable work to develop an API is beyond me). With mechanize, this problem turns into an enjoyable coding session — with this gem, you can interact with a website as though you were using a browser; submit forms, follow links, screen scrape, etc. all from an intuitive Nokogiri powered API.

# Initialize new mechanizer
agent = Mechanize.new

# Load google homepage and grab the search form
agent.get 'http://google.com'
form = agent.page.forms.first

# Set the search query and submit
form.q = 'nybblr'
search_page = form.submit

Oh, and one last jewel…rails

How could I possibly discuss all of these gems without mentioning that Ruby on Rails itself is a whopping gem of its own? If you’re not using rails as your web development framework, you should. Run gem install rails right now and start riding the rails!