See also Plugins
SomeImportantPluginNotes – before you start
# ruby script/generate plugin acts_as_fox
This creates a new directory called “acts_as_fox” under your_app/vendor/plugins.
In the init.rb file, add the following:
require 'acts_as_fox' # reopen ActiveRecord and include all the above to make # them available to all our models if they want it ActiveRecord::Base.class_eval do include Foo::Acts::Fox end # alternatively, you can use this call: # ActiveRecord::Base.send :include, Foo::Acts::Fox
In the lib/acts_as_fox.rb file, add your code:
require 'active_record'
module Foo
module Acts #:nodoc:
module Fox #:nodoc:
def self.included(mod)
mod.extend(ClassMethods)
end
# declare the class level helper methods which
# will load the relevant instance methods
# defined below when invoked
module ClassMethods
def acts_as_fox
# this is at the class level
# add any class level manipulations you need here, like has_many, etc.
extend Foo::Acts::Fox::SingletonMethods
include Foo::Acts::Fox::InstanceMethods
end
end
# Adds a catch_chickens class method which finds
# all records which have a 'chickens' field set
# to true.
module SingletonMethods
def catch_chickens
find(:all, :conditions => ['chickens = ?', true])
end
# etc...
end
# Adds instance methods.
module InstanceMethods
def eat_chicken
puts "Fox with ID #{self.id} just ate a chicken"
end
end
end
end
end
Finally use your method in your classes
class Thing < ActiveRecord::Base acts_as_fox end
Jamis Buck suggested using some name like Foo in the above because “this will allow (potentially) multiple developers to develop identically-named features without conflict.” Other people use “ActiveRecord” in place of the three “Foo”. Jamis doesn’t like this use of ActiveRecord. He says “I’ve noticed many plugin developers taking this particular route, and I’d like to discourage it, strenuously. There really is no need to add your own acts to the ActiveRecord::Acts namespace. Instead, I’d encourage the creation of your own Acts namespace like Foo”
HowTosPlugins – Some tutorials to get started
Note: if you ensure a one-to-one mapping between the class level ‘declaration’ method (acts_as_fox) and the module that defines the instance methods for that declaration, you can define more than one class level helper. So you would probably rename module SingletonMethods to something like FoxMethods. This would allow you to define acts_as_fox and acts_slightly_foxy (module SlightlyFoxy) and acts_as_fox_only_on_thursdays (module FoxyThursdays) all in the same plugin.