创建几乎完全相同的2个插头,但略有不同

Kuq*_*uqa 0 elixir phoenix-framework

我有自己的插头模块:

defmodule Module1 do

  def init(opts) do
    opts
  end

  def call(conn, _opts) do
    # if some_condition1
    # something
  end

  # other stuff
end
Run Code Online (Sandbox Code Playgroud)

在router.ex中

  pipeline :pipeline1 do
    plug(Module1)
  end

  scope "/scope", MyApp, as: :scope1 do
    pipe_through([:browser, :pipeline1])
    # .......
Run Code Online (Sandbox Code Playgroud)

现在我想使用相同的模块Module1创建第二个管道和范围:

  pipeline :pipeline2 do
    plug(Module1)
  end

  scope "/scope2", MyApp, as: :scope2 do
    pipe_through([:browser, :pipeline2])
    # .......
Run Code Online (Sandbox Code Playgroud)

但是,如果我要创建第二个模块,那么区别仅在于:

 def call(conn, _opts) do
    # if some_condition1 and some_condition2
    # something
  end
Run Code Online (Sandbox Code Playgroud)

也就是说,我只添加了"some_condition2",其他一切都保持不变.

现在,我该怎么做?我是否必须创建与Module1完全相同的模块Module2并轻轻地更改"call"?它会导致代码重复.

Dog*_*ert 7

这就是opts插件的意思.您可以从plug通话中传递它,然后在内部使用它call:

pipeline :pipeline1 do
  plug Module1, check_both: false
end

pipeline :pipeline2 do
  plug Module1, check_both: true
end
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

现在pipeline1,opts[:check_both]将是假的,而且pipeline2,它将是真的.


我在这里传递一个关键字列表,但是你可以传递任何东西,即使只是一个true或者false如果这足够(这应该比关键字列表快一点).

您也可以使用optsin 进行一些预处理init/1.现在它只返回初始值.