Plugins are self-contained libraries made specially for Rails. They are a great way to reuse someone else’s code or to package your own code for reuse.
This is the first of a three part tutorial on writing plugins for Ruby on Rails.
Unlike gems, plugins are installed directly into a specific Rails app. This makes it easier to deploy them remotely along with an entire application.
I mentioned previously that the following places are good sources for plugins:
Discover and Install
Once you’ve found a plugin that does what you want, install it into your existing Rails app like this:
# Install a plugin from a known source
./script/plugin install calendar_helper
# Similar on Windows
ruby script/plugin install calendar_helper
# Install from a specific url
./script/plugin install http://topfunky.net/svn/plugins/calendar_helper
# Install by linking it directly within Subversion
./script/plugin install -x calendar_helper
If the script doesn’t automatically find the plugin, run the discovery action which looks for all the sources on the Rails wiki:
# Import new plugin sources
There are also a few other arguments to the plugin script. Run ./script/plugin with no arguments to see all the options.
To uninstall a plugin, you can:
Delete the specific folder for the plugin
Remove it with svn delete
Unlink it with svn propdel svn:externals vendor/plugins/
Writing a Plugin
Just like riding a bike or learning to swim, being able to write a plugin is a great skill. If you’ve written any Ruby code at all, you’re halfway there.
There are a few things that can only be done with a plugin (like writing your own generator). For the rest, you’ll appreciate the ability to share common code between your applications or with other developers.
Plugin-Man, Plugin-Man, Doing the Things a Plugin Can
Plugins can do almost anything that a Rails app can, plus a little more. Here’s a short summary of the kinds of things a plugin can do:
Models: This is the easiest kind of plugin to write. Drop a model in the plugin’s lib folder and you’ll be ready to go.
View Helpers: A helper method can be slurped into the rest of your app (the technical term is mixin). Also quite easy.
Controllers: You can’t directly write a controller plugin, but you can write a generator that copies a controller to your app/controllers directory. Intermediate difficulty.
rake Tasks: Better living through automation! Drop a .rake file into the tasks folder and you can reuse your tasks!
Test assertions: Can easily be mixed-in to your tests.
Unit and Functional tests: As with controllers, these can be generated. Intermediate difficulty.
Other functionality: There are plenty of other things you might want to do with your app: connect to a payment processor, send messages to the Basecamp API, use a Campfire bot, generate graphs, etc. These can be done easily with plugins.
You can see the basic layout of a plugin by running the standard plugin generator:
# Use the generator to make a transmogrifier plugin
./script/generate plugin transmogrifier
Here’s the basic folder structure:
| |– transmogrifier.rb
| |– transmogrifier_tasks.rake
| |– transmogrifier_test.rb
None of these files are necessary, but they each do different things. You might write a plugin that only has a tasks folder, or another that only has a lib folder. Here is what each piece does:
init.rb: Runs everytime the Rails app is started. Useful for mixing-in a helper module so all your views can use it.
install.rb: Runs one time only when the plugin is first installed. Can be used to copy required files or to show installation instructions.
Rakefile: Generates documentation and runs tests for the plugin.
lib/: Contains actual Ruby code. New models and other libraries in this folder will be automatically available to your Rails app. Helpers can be included specially, using the init.rb file.
tasks/: Drop a .rake file here as you would in lib/tasks. It’s automatic…no other action is needed!
test/: Write tests to verify the operation of your plugin.
generators/: Used for passive code generation, like the built-in scaffolds.
rdoc/: Contains generated documentation from the rake rdoc task.
MIT-LICENSE: It helps to paste this, or your preferred license. There’s nothing stopping you from making a plugin and selling it commercially or just keeping it internally for your company. If you have proprietary business logic in your plugin, you probably don’t want to make it available to the public!