Jonathan Martin
Ruby on Rails: Top 10 Gems
~ by Jonathan Martin
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <%= 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.
1 2 3 4 5 6 | <%= 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.
1 2 3 4 5 6 7 8 | # /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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # /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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # /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 |
1 2 3 4 5 6 7 8 | # /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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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.
1 2 3 4 5 6 7 8 9 10 | # 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!