module BlahPlugin VERSION = '1.0.0' class << self # add plugin to AR only if it hasn't been included before, # which may cause stack-level-too-deep errors if you're aliasing methods # def enable_activerecord return if ActiveRecord::Base.respond_to? :acts_as_blah ActiveRecord::Base.extend BlahPlugin::Macro end end module Macro # his class level method injects the rest of the plugin behaviour in the affected class. # use like this: # class Post < ActiveRecord::Base # acts_as_blah # end # def acts_as_blah(opts = {:some_option => true} # don't include modules twice return if self.included_modules.include?(BlahPlugin::InstanceMethods) # include class and instanc methods extend BlahPlugin::ClassMethods include BlahPlugin::InstanceMethods # do something else, like initializing options end end module ClassMethods # class methods injected by the plugin, alias_method chaining, macro calls (has_many, after_save, validates),etc. end module InstanceMethods # instance methods injected by the plugin. callbacks, etc. end end require 'rubygems' require 'active_record' # enable the thing! BlahPlugin.enable_activerecord