Ruby on Rails
HowToWriteAnActsAsFoxPlugin

See also Plugins

SomeImportantPluginNotes – before you start

Step 1

# ruby script/generate plugin acts_as_fox

This creates a new directory called “acts_as_fox” under your_app/vendor/plugins.

Step 2

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

Step 3

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

Step 4

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.