Ruby methods question

I followed the online tutorials on how to write plugins. So I have
acts_as_fox.rb:

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
      class_eval do
        extend Foo::Acts::Fox::SingletonMethods
      end
      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

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

and Thing.rb

class Thing < ActiveRecord::Base
acts_as_fox
end

My question I want to change the acts_as_fox to something like:

acts_as_fox :pass_something

where I can pass a symbol as a value to the acts_as_fox method.

I tried to modify the working example with no luck. Can someone please
point me in the right direction?

On 3/11/07, [email protected] [email protected] wrote:

    mod.extend(ClassMethods)
      include Foo::Acts::Fox::InstanceMethods
    # etc...

end

I tried to modify the working example with no luck. Can someone please
point me in the right direction?

Don’t know anything about plugins, though I suppose

  module ClassMethods
    def acts_as_fox(arg)
      do_something(arg)
      class_eval do
        extend Foo::Acts::Fox::SingletonMethods
      end
      include Foo::Acts::Fox::InstanceMethods
    end
  end

should suffice. If it doesn’t work, please specify 1. what are you
trying to achieve, 2. what did you try (preferably include the code)
and 3. what did you get (include error messages and/or describe the
wrong behaviour)

This code is a copy-paste from the tutorial. To find out what’s wrong
it’s important to see your changes.

Your code works. I want to make the acts_as_chicken :something to be
available only to those ActiveRecord subclasses that uses the
acts_as_chicken declaration. How can I accomplish that?

        extend Foo::Acts::Fox::SingletonMethods
      end
      include Foo::Acts::Fox::InstanceMethods
    end
  end

Loading development environment.

t = Thing.new
=> #<Thing:0x31e3dec @new_record=true, @attributes={“chickens”=>nil}

t = Thing.new :chickens => true
=> #<Thing:0x31d7b28 @new_record=true, @attributes={“chickens”=>true}

t.catch_chickens
NoMethodError: undefined method catch_chickens' for #<Thing: 0x31d7b28> from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/ active_record/base.rb:1861:inmethod_missing’
from (irb):3

Thing.catch_chickens
=> [#<Thing:0x31d3618 @attributes={“id”=>“1”, “chickens”=>“1”}]

t.eat_chicken
ArgumentError: wrong number of arguments (0 for 1)
from (irb):5:in `eat_chicken’
from (irb):5

?> df
NameError: undefined local variable or method `df’ for #<Object:
0x3349ec>
from (irb):7

t.eat_chicken(:booie)
Fox with ID just ate a chicken with name booie
=> nil

t = Thing.new :chickens => true
=> #<Thing:0x31cb29c @new_record=true, @attributes={“chickens”=>true}

t.eat_chicken
ArgumentError: wrong number of arguments (0 for 1)
from (irb):10:in `eat_chicken’
from (irb):10

quit
14:07:07:~/work/plugins/fox > script/console
Loading development environment.

t = Thing.new :chickens => true
=> #<Thing:0x31e2ac8 @new_record=true, @attributes={“chickens”=>true}

t.eat_chicken
NameError: undefined local variable or method name' for #<Thing: 0x31e2ac8> from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/ active_record/base.rb:1861:inmethod_missing’
from ./script/…/config/…/config/…/vendor/plugins/
acts_as_fox/lib/acts_as_fox.rb:36:in `eat_chicken’
from (irb):2

?> k
NameError: undefined local variable or method `k’ for #<Object:
0x3349ec>
from (irb):4
17:54:47:~/work/plugins/fox > script/console
Loading development environment.

t = Thing.new :chickens => true
good
=> #<Thing:0x31e29b0 @new_record=true, @attributes={“chickens”=>true}

I don’t want to pollute the ActiveRecord class by making the
acts_as_chicken available to all of its classes. It must be made
available only to the sub-classes of the ActiveRecord that has the
acts_as_chicken declaration.

On Mon, 12 Mar 2007, [email protected] wrote:

I don’t want to pollute the ActiveRecord class by making the acts_as_chicken
available to all of its classes. It must be made available only to the
sub-classes of the ActiveRecord that has the acts_as_chicken declaration.

module ActsAsChicken

stuff

end

class ActiveRecord
def self.inherited other
super
ensure
other.extend ActsAsChicken
end
end

-a

It’s still really unclear what you’re asking (at least to me). Are
you saying you want acts_as_fox to work only if the object has fox ==
true (and the same for chicken)?

Or, are you talking about single table inheritance? If so, you can
just add acts_as_XXX to your sub-classes as appropriate…

end
end

What is happening in the opened up ActiveRecord class? I am still
learning Ruby. TIA.