Ruby On Rails, Design, Simplicity, Web 2.0, Ajax, Mac and Tons of Pizza.

Dec 31

Tutorial: a simple act_as plugin for ruby on rails

Posted by Sandro Paganotti in Ruby on Rails - comments are closed digg this add to delicious

Acts_as_commentable, acts_as_flaggable, acts_as… it seems that this kind of plug-ins is popping out from everywhere, so in this tutorial I’ll try to explain how to get your personal act_as plugin.

Chapter 1: Theory of an act_as

The key-word for a plug-in of this kind is ‘mixing’; mixing means using Modules nested inside Classes. In details this is how an acts_as plugin works:

  1. inject into your Activerecord::Base class the module containing the function named ‘act_as_* ’
  2. put your ‘act_as_* ’ into your target model
  3. in the ‘act_as_* ’ function include the module that contains the instance functions and extend the module with the class functions

Ok, it seems easy, let’s try it out.

Chapter 2: Practice time

In few steps, we’re going to create a very easy act_as plugin: act_as_random. Our aim is to provide a random method that returns a random row from the choosen model. First, let’s create a rails application:


rails myactas 

Now we’re ready to create our plugin:


ruby script/generate plugin act_as_random 

We’re just 2 steps far from the end, the next one is open /vendor/plugins/act_as_random/lib/act_as_random.rb and put this code inside:


module MyMod
module Acts
   module Roled 
     # included is called from the ActiveRecord::Base
     # when you inject this module

     def self.included(base) 
      # Add acts_as_roled availability by extending the module
      # that owns the function.
       base.extend AddActsAsMethod
     end 

     # this module stores the main function and the two modules for
     # the instance and class functions
     module AddActsAsMethod
       def acts_as_random(options = {})
        # Here you can put additional association for the
        # target class.
        # belongs_to :role
        # add class and istance methods

         class_eval <<-END
           include MyMod::Acts::Roled::InstanceMethods    
         END
       end
     end

     # Istance methods
     module InstanceMethods 
      # doing this our target class
      # acquire all the methods inside ClassMethods module
      # as class methods.

       def self.included(aClass)
         aClass.extend ClassMethods
       end 

       module ClassMethods
         # Class methods  
         # Our random function.
        def random
            find(:first,order=>"RAND()");
        end
       end 

     end 
   end
end
end 

The last step involving our plugin is injecting our module inside ActiveRecord::Base, to achieve this just put this code inside our init.rb (in the plugins/myactas directory):


require 'acts_as_random'
ActiveRecord::Base.send(:include, MyMod::Acts::Roled) 

Done! Now we’re ready to use our new shiny plugin!

Chapter 3: Riding our plugin

Create a test model inside our app:


ruby script/generate model country 

then fill our test model with some data using this sql file: countries.sql (i know, no migration and no yaml but it is just because is a test model :P ).

Now open app/models/country.rb and write:


# this is just because our table primary key name
# is not 'id'
self.primary_key = "Code" 
acts_as_random 

In order to test this thing works, let’s open the console:


ruby script/console
>> puts "Today destination: " + Country.random.Name + " !!" 
"Today destination: Netherlands !!" 
=> nil 

WOW! It works! That’s all folks!

Sandro.

Post a comment

Categories:

Tags:

Powered by Mephisto, Valid XHTML 1.1, Valid CSS - Supported by Wave Factory