我正试图在Rails项目中干掉装饰器。
基本上,我想将任何缺少的方法委托给资源对象(或资源对象的类)。
这是一个简化的例子
# Decorator base class
class Decorator
attr_accessor :resource
private
def method_missing(name, *args, &block)
self.resource.send(name, *args, &block)
end
# infinite recursion happens here
def self.method_missing(name, *args, &block)
self.resource.class.send(name, *args, &block)
end
end
# Decorator class that will be used
class UserCreator < Decorator
attr_reader :user
def initialize(params)
@user = User.new(params[:user])
self.resource = @user
end
def save
# do special stuff with user object
if @user.save
# perhaps do some more stuff after the save
true
else
# perhaps handle the error here
false
end
end
end
# A simple controller example
class SomeController < ApplicationController
respond_to :json
def create
@user = UserCreator.new(params)
if @user.save
render :json => @user
else
render :json => @user.errors
end
end
end
但是,在类Decorator
中,在类(单例)方法self.method_missing
中发生无限递归。它将resource
作为该方法中的name
参数传递。
我试图围绕这里发生的事情的控制流程。方法resource
通过Decorator
存在于基础attr_accessor
类中,所以我认为,子类UserCreator
也有此方法。所以我不确定为什么它认为resource
是一种缺失的方法。如果我摆脱了Decorator
超类并且只在method_missing
类中实现了UserCreator
,那么一切都按预期工作。
非常感谢任何实现此基类以按预期工作的帮助,因此我不必在每个装饰器中实现相同的method_missing
方法。
答案 0 :(得分:2)
第二个method_missing
是一个类方法。因此,在此方法中self
引用类,而不是实例。
但是,该方法尝试访问self.resource
,它是实例的属性,而不是类。
由于Decorator
类没有resource
属性,因此再次调用method_missing
......再次......再次调用...
我试图围绕这里发生的事情的控制流程。 方法资源存在于底层Decorator类中,通过attr_accessor,
它存在于Decorator类的实例中,但不存在于类本身中。
所以我想,子类UserCreator也有这种方法。
UserCreator子类的实例拥有它,但不包含子类本身。