我正在尝试编写一个 DSL 来包装 Mongoid 的聚合管道(即 Mongo DB)。
我制作了一个模块,当包含该模块时,它添加了一个接受块的类方法,它将请求传递给 Mongoid 的对象(通过缺少方法)。
所以我可以这样做:
class Project
include MongoidAggregationHelper
end
result = Project.pipeline do
match dept_id: 1
end
#...works!
“match”是Mongoid的聚合管道上的一个方法,被拦截并传递。
但是在块外设置的实例变量不可用,因为它是在代理类的上下文中执行的。
dept_id = 1
result = Project.pipeline do
match dept_id: dept_id
end
#...fails, dept_id not found :(
有什么方法可以在块中传递/重新定义外部实例变量?
以下是修剪后的代码:
module MongoidAggregationHelper
def self.included base
base.extend ClassMethods
end
module ClassMethods
def pipeline &block
p = Pipeline.new self
p.instance_eval &block
return p.execute
end
end
class Pipeline
attr_accessor :cmds, :mongoid_class
def initialize klass
self.mongoid_class = klass
end
def method_missing name, opts={}
#...proxy to mongoid...
end
def execute
#...execute pipeline, return the results...
end
end
end