The Dark Art of Rails Plugins By James Adam of reevoo.com = Anatomy of a plugin A folder in vendor/plugins lib-folder is the most important folder - Where you put your Ruby code Added to $LOAD_PATH alphabetically or using config.plugins == Init.rb - Evaluated near the end of rails initialization - evaluated in order of config.plugins - Special variables available - config, directory, name - see source of Rails::Plugin == Other files install.rb: Will be run only if you use ./script/plugin tasks: Any files here that ends in .rake should contain rake-tasks generators: Automatically available as generated when placed here test: (doh!) = Writing plugins == Sharing code Common files and rake tasks in lib and tasks == Sample module Friendly def hello "hi from #{self}" end end = Class methods in modules Can't do this: module Friendly self.is_friendly? true end end Instead do this: module Friendly::ClassMethods is_friendly? true end end class Person extend Friendly::ClassMethods end class << Person def salutations ... end end = Enhancing Rails We don't want every subclass of ActiveRecord (i.e.) to get our methods included Ruby class definitions are code - it blows your mind! - So, has_many is a class method = Changing behaviour acts_as_archivable - when a record is deleted, save a YAML version. Just in case. Core: module Archivable def archive_to_yaml File.open("#{id}.yml", 'w) do |f| f.write self.to_yaml end end end Tying it into ActiveRecord: (We can't redefine methods in a class by simply including a module) def destroy_with_archiving ... end alias_method_chain :destroy, :archiving super can also be used, as explained here: http://blog.fallingsnow.net/2008/04/02/super-is-your-friend/ = Tips #2: Developing plugins Rails only loads plugin code once Fix this by adding to config/environments/development.rb: config.after_initialize do Dependencies.load_once_paths. delete_if do |path| path =~ /vendor\/plugins/ end end end #3: Gems as plugins - Coming in Rails 2.1 - Add rails/init.rb - require "rubygems" in environment.rb