1
我正在尝试编写一个DSL来包装Mongoid的聚合管道(即Mongo DB)。根据实例eval将实例变量传递给DSL
我做了一个模块,当包含它时,添加一个类方法,接受一个块,它交给一个将请求传递给Mongoid的对象(通过缺少方法)。
所以我可以做:
class Project
include MongoidAggregationHelper
end
result = Project.pipeline do
match dept_id: 1
end
#...works!
“匹配”是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
你可以试一下'def pipeline(* args,&block)'和'Project.pipeline dept_id:dept_id do'吗? – MrYoshiji
好的建议@MrYoshiji,在生产代码中我这样做,它的工作原理。我希望避免必须将变量作为选项散列传递,然后使用之前声明的变量(如果有的话)。 –
我发布了一个替代答案 – MrYoshiji