Rails プロジェクトでデコレータを DRY しようとしています。
基本的に、欠落しているメソッドをリソース オブジェクト (またはリソース オブジェクトのクラス) に委譲したいと考えています。
簡単な例を次に示します
# 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
てベースクラスにメソッドが存在するので、サブクラスにもこのメソッドがあると思いました。そのため、メソッドが欠落していると考える理由がわかりません。スーパークラスを取り除き、クラスにs を実装するだけで、すべてが期待どおりに機能します。Decorator
attr_accessor
UserCreator
resource
Decorator
method_missing
UserCreator
method_missing
この基本クラスを実装して期待どおりに動作させるための助けがあれば大歓迎です。そのため、すべてのデコレーターで同じメソッドを実装する必要はありません。