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
bundleThat’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 ActsAsLuckythen 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.





Add a comment



Add a comment