Elixir Phoenix插头及其放置位置

时间:2018-11-05 17:20:29

标签: elixir phoenix-framework

我目前正在学习Elixir Phoenix框架。我现在停留在https://hexdocs.pm/phoenix/routing.html#forward上,它是关于如何使用forward命令的。

它是写在这里的,不需要立即学习Plugs,因此,如果我想尝试使用forward命令,我可以将他们对Plug 的实现复制到我的应用程序中。但是到底在哪里?我试图进行搜索,并尝试使用发现的内容,但是我做错了事。

这就是我的.\lib\hello_web\router.ex文件中的范围:

scope "/", HelloWeb do
  pipe_through :browser # Use the default browser stack

  get "/", PageController, :index
  forward "/jobs", BackgroundJob.Plug, name: "Hello, Phoenix"
end

这是一个插件的代码:

defmodule BackgroundJob.Plug do
  def init(opts), do: opts
  def call(conn, opts) do
    conn
    |> Plug.Conn.assign(:name, Keyword.get(opts, :name, "Background Job"))
    |> BackgroundJob.Router.call(opts)
  end
end

defmodule BackgroundJob.Router do
  use Plug.Router

  plug :match
  plug :dispatch

  get "/", do: send_resp(conn, 200, "Welcome to #{conn.assigns.name}")
  get "/active", do: send_resp(conn, 200, "5 Active Jobs")
  get "/pending", do: send_resp(conn, 200, "3 Pending Jobs")
  match _, do: send_resp(conn, 404, "Not found")
end

我现在应该对Plugs和Phoenix几乎一无所知,所以这可能很明显,但是我确实呆了几个小时。谁能帮我找出放置代码的位置?

2 个答案:

答案 0 :(得分:0)

欢迎来到stackoverflow。

您尚未发布遇到的错误,但我猜您的问题是模块命名。在phoenix中,在scope块中使用的模块将以您为该作用域提供参数的模块名称作为前缀(在本例中为HelloWeb)。因此,将您的插件模块的名称更改为HelloWeb.BackgroundJob.Plug就足够了。另外,您无法将范围界定模块传递给scope

scope "/" do
  pipe_through :browser # Use the default browser stack

  get "/", HelloWeb.PageController, :index
  forward "/jobs", BackgroundJob.Plug, name: "Hello, Phoenix"
end

在这种情况下,请注意更改PageController-> HelloWeb.PageController

就放置位置而言-.ex中的任何lib文件都可以使用,因为长生不老药只编译了所有文件。实际上,您只需将代码粘贴到router.ex中即可对其进行快速测试。按照约定,文件名应遵循模块名称,因此HelloWeb.BackgroundJob.Plug应该位于lib/hello_web/background_job/plug.ex中。

答案 1 :(得分:0)

是的,我了解您的困惑。 可以在指南中更清楚地解释它。

如果将模块名称传递给合并范围,则传入的模块名称将作为该范围内所有模块的前缀。

例如,假设您传入的模块名称为HelloWeb, 当您将其传递到这样的范围时:

scope "/", HelloWeb do
  ...
  get "/", PageController, :index
  forward "/jobs", BackgroundJob.Plug
end

"/"路线将寻找HelloWeb.PageController
"/jobs"路线将寻找HelloWeb.BackgroundJob.Plug

因此,为了使您的错误消失,我假设是这样的:

helloweb.backgroundjob.plug.init/1 is undefined

您可以从范围中删除传入的模块名称,然后手动在模块名称前添加BackgroundJob.Plug,如下所示:

scope "/",  do
  ...
  get "/", HelloWeb.PageController, :index
  forward "/jobs", BackgroundJob.Plug
end

或者,也许可以保存一些重复的输入并改为添加“ / jobs”范围,例如:

  scope "/", HelloWeb do
    ...
    get "/", PageController, :index
  end

  scope "/jobs" do
    forward "/", BackgroundJob.Plug, name: "Hello Phoenix"
  end

请注意,示例中的...代表了pipe_through的方法和其他途径,对于传达此想法而言并非必不可少。

希望有帮助。