我有自己的插件模块:
defmodule Module1 do
def init(opts) do
opts
end
def call(conn, _opts) do
# if some_condition1
# something
end
# other stuff
end
在router.ex
中 pipeline :pipeline1 do
plug(Module1)
end
scope "/scope", MyApp, as: :scope1 do
pipe_through([:browser, :pipeline1])
# .......
现在我想使用相同的模块Module1创建第二个管道和范围:
pipeline :pipeline2 do
plug(Module1)
end
scope "/scope2", MyApp, as: :scope2 do
pipe_through([:browser, :pipeline2])
# .......
但是,如果我要创建第二个模块,那么区别仅在于:
def call(conn, _opts) do
# if some_condition1 and some_condition2
# something
end
也就是说,我只添加了#34; some_condition2",其他一切都保持不变。
现在,我该怎么做?我是否必须创建与Module1完全相同的模块Module2,然后轻轻地改变" call"?它会导致代码重复。
答案 0 :(得分:7)
这就是Plug中opts
的意思。您可以通过plug
来电传递它,然后在call
内使用它:
pipeline :pipeline1 do
plug Module1, check_both: false
end
pipeline :pipeline2 do
plug Module1, check_both: true
end
defmodule Module1 do
def init(opts), do: opts
def call(conn, opts) do
if opts[:check_both] do
# if some_condition1 and some_condition2 do something...
else
# if some_condition1 do something...
end
end
end
现在在pipeline1
,opts[:check_both]
将为false,在pipeline2
中,它将为真。
我在这里传递了一个关键字列表,但你可以传递任何内容,即使只有一个true
或false
,如果这足够(也应该比关键字列表快一点)
您还可以在opts
中使用init/1
进行一些预处理。现在它只返回初始值。