9780596521424
plugins_id62185.html

Chapter 15. Plugins

Plugins let developers share common functionality across applications, without duplicating code. They let developers share solutions for common problems like authentication, tagging, and search that aren't addressed by Rails core. Because there is no one official solution to these problems, multiple solutions can flourish and the Rails community remains agile and inventive.

Installing Plugins

As of Rails 3.2 plugins in Rails are encouraged to be straight-up Ruby gems, making installation as simple as adding them to your Gemfile and running bundle. Let’s walk through an example using the will_paginate gem:

When a user has asked for 5000 results of something, you probably don’t want to serve all of it back up in one shot. Instead, you want to paginate results. Pagination code is not what you want to spend time writing however. The good news is that a great gem exists to do it: will_paginate.

To install will_paginate just add it to your Rails project’s Gemfile:

gem 'will_paginate'

then run

bundle

That’s it for installation. To implement it, use code like this in your controller:

@posts = Post.paginate(:page => params[:page], :per_page => 30)

and code like this in your view to display links to the pages; (the @posts var will hold the up-to-30 posts for the current page)

<%= will_paginate @posts %>

For more on will_paginate see https://github.com/mislav/will_paginate

Popular gems exist for things like running delayed jobs, exception notification, and authentication.

Writing a Plugin

Rails plugins are just Ruby libraries, usually in the form of Ruby gems or entries in your application’s lib directory. They used to not be, especially since before Rails 3.2 but that fortunately changed. Let’s not talk about that.

Instead, let’s look at a simple extension to Rails. We’re going to start small and structure this plugin as a single file in lib which arguably makes it just a regular library. Again, the good news is that there’s no difference.

Let’s write a plugin called acts_as_lucky plugin that adds a lucky_number method to Active Record objects, and a find_by_lucky_number to the Active Record class.. We’ll also only make these methods available conditionally, depending on if the model calls acts_as_lucky.

Hooking into Active Record

In Ruby, when you include a module in a class, the methods in the module become instance methods on that class. If you extend a class with a module, the module's methods become class methods. We can use the included hook that Ruby provides to automatically extend any class that includes our module.

With that in mind, let’s extend ActiveRecord with the ActsAsLucky module and introduce its instance methods and class methods accordingly:

module ActsAsLucky
  def acts_as_lucky
    include InstanceMethods
    extend ClassMethods
  end
  
  module InstanceMethods
    # The lucky number should be the last digit of the model's ID
    # Example:
    #   user.id           #=> 123
    #   user.lucky_number #=> 3
    def lucky_number
      id.to_i % 10
    end
  end

  module ClassMethods
    def find_by_lucky_number(number)
      where("id % 10 = ?", number)
    end
  end
end

ActiveRecord::Base.extend ActsAsLucky

then create a file config/initializers/acts_as_lucky.rb with the following:

require Rails.root.join('lib/acts_as_lucky')

which lets us add the following to an assumed User model

class Person < ActiveRecord::Base
  acts_as_lucky
end

and now run code like

>> 27.times { User.create }
=> 27

>> user = User.last
=> #<User id: 27>

>> user.id
=> 27

>> user.lucky_number
=> 7

>> User.find_by_lucky_number(7)
=> [#<User id: 7>, #<User id: 17>, #<User id: 27>]

When you’re ready to move your library out to a proper Ruby gem of its own for easier distribution/fame and fortune, then change directories to wherever you write new projects and create the gem:

bundle gem acts_as_lucky

Take a look at the results and drop in your code from earlier. Refer to rubygems.org for how best to structure your gem and publish it. Once it’s published, you can remove lib/acts_as_lucky.rb and its initializer and add your gem to your Gemfile like all the rest.

Rails generators are also game for creation; see Rails Guides for a walkthrough.

Site last updated on: December 11, 2012 at 10:21:28 PM PST
Cover for Rails 3 in a Nutshell

View 2 comments

  1. bitzesty – Posted Oct. 26, 2009

    might be worth mentioning the features of the other branches.

  2. goodwill – Posted Nov. 16, 2009

    Probably should talk a bit about authentication (AuthLogic), resource_controller, some integration with non-standard js framework (e.g. jQuery) would be great.

Add a comment

View 1 comment

  1. sdsykes – Posted Oct. 20, 2009

    More recent version: script/plugin install git://github.com/rails/exception_notification.git

Add a comment