#Create a namespace for your modules and classes module ActsAsMonkey #Create a module for extensions to AR. I know all this seperating #methods into ClassMethods, SingletonMethods and InstanceMethods and #using all this Ruby magic to actually include them can seem overly #complicated, but there are a few advantages to this approach. It all #depends on what you're doing, but for an acts_as-style plugin you only #want to include SingletonMethods and InstanceMethods when the acts_as #method is run. It also makes it easier to document them. module ActiveRecordExtensions #Gets run when this module is included into another module or class. #This way you can just include ActiveRecordExtensions in AR::B, and #it'll take care of the rest itself. def self.included(base) #base == ActiveRecord::Base, usually base.send(:extend, ClassMethods) end #Class methods will be available to all classes that inherit AR::B module ClassMethods #This method extends the class in which it's run def acts_as_monkey extend SingletonMethods include InstanceMethods #As this is a class method, you have access to all the other #class methods in AR::B too, such as validations validates_presence_of :name #And callbacks before_validation :check_color before_save :upcase_name end end #Singleton methods are added to a single class. I.e. they're #class methods, but only for the classes that have "acts_as_monkey" #in them. module SingletonMethods def default_color 'brown' end end #Each instance of a class that acts_as_monkey will have these methods. module InstanceMethods def smile 'Monkey smile :-]' end private def upcase_name self.name.upcase! end def check_color if respond_to?('color=') self.color ||= self.class.default_color end end end end #Will be available in all controllers module ActionControllerExtensions #before_filter has to be run _after_ this module #has been included into AC::B, because it's not going #to be available until then. def self.included(base) #and it doesn't hurt to check then either base.send(:before_filter, :foo) if respond_to?(:before_filter) end #Was this page requested by a monkey? def monkey_request? request.env['User-Agent'] =~ /monkey/ end private def foo #.. end end #Will be available in views. "Helper methods" module ActionViewExtensions def whatever(monkey) "I'm the whatever monkey, my name is #{monkey.name} and my fur is #{monkey.color}" end end end