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:in
method_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:in
method_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.