Permalink
Browse files

method_missing is no longer overridden on instances provided you decl…

…are your custom method_missing *before* specifying the model is_paranoid
  • Loading branch information...
1 parent 967510b commit bc929ad336924c09af081dedcfc123d4d01331e9 Jeffrey Chupp committed May 20, 2009
Showing with 33 additions and 7 deletions.
  1. +16 −7 lib/is_paranoid.rb
  2. +9 −0 spec/is_paranoid_spec.rb
  3. +8 −0 spec/models.rb
View
@@ -86,7 +86,7 @@ def restore(id, options = {})
# find_with_destroyed and other blah_with_destroyed and
# blah_destroyed_only methods are defined here
- def method_missing name, *args
+ def method_missing name, *args, &block
if name.to_s =~ /^(.*)(_destroyed_only|_with_destroyed)$/ and self.respond_to?($1)
self.extend(Module.new{
if $2 == '_with_destroyed'
@@ -110,16 +110,16 @@ def method_missing name, *args
define_method name do |*args|
self.with_exclusive_scope do
with_scope({:find => { :conditions => ["#{self.table_name}.#{destroyed_field} IS NOT ?", field_not_destroyed] }}) do
- self.send($1, *args)
+ self.send($1, *args, &block)
end
end
end
end
})
- self.send(name, *args)
+ self.send(name, *args, &block)
else
- super(name, *args)
+ super(name, *args, &block)
end
end
@@ -140,8 +140,17 @@ def restore_related klass, key_name, id, options #:nodoc:
end
module InstanceMethods
+ def self.included(base)
+ base.class_eval do
+ unless method_defined? :method_missing
+ def method_missing(meth, *args, &block); super; end
+ end
+ alias_method :old_method_missing, :method_missing
+ alias_method :method_missing, :is_paranoid_method_missing
+ end
+ end
- def method_missing name, *args
+ def is_paranoid_method_missing name, *args, &block
# if we're trying for a _____with_destroyed method
# and we can respond to the _____ method
# and we have an association by the name of _____
@@ -164,9 +173,9 @@ def method_missing name, *args
end # end
}
)
- self.send(name, *args)
+ self.send(name, *args, &block)
else
- super(name, *args)
+ old_method_missing(name, *args, &block)
end
end
View
@@ -198,6 +198,15 @@
sticker.android.should == nil
sticker.android_with_destroyed.should == nil
end
+
+ it "should not break method_missing's defined before the is_paranoid call" do
+ # we've defined a method_missing on Sticker
+ # that changes the sticker name.
+ sticker = Sticker.new(:name => "Ponies!")
+ lambda{
+ sticker.some_crazy_method_that_we_certainly_do_not_respond_to
+ }.should change(sticker, :name).to(Sticker::MM_NAME)
+ end
end
describe 'alternate fields and field values' do
View
@@ -42,6 +42,14 @@ class Memory < ActiveRecord::Base #:nodoc:
end
class Sticker < ActiveRecord::Base #:nodoc
+ MM_NAME = "You've got method_missing"
+
+ # this simply serves to ensure that we don't break method_missing
+ # if it is implemented on a class and called before is_paranoid
+ def method_missing name, *args, &block
+ self.name = MM_NAME
+ end
+
is_paranoid
belongs_to :android
end

0 comments on commit bc929ad

Please sign in to comment.