Elixir Phoenix 插头及其放置位置
Elixir Phoenix Plugs and where to place them
我目前正在学习 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 几乎一无所知,所以这可能是显而易见的事情,但我真的在那里呆了几个小时。谁能帮我找出该代码的放置位置?
欢迎使用 Whosebug。
你没有发布你遇到的错误,但我猜你的问题是模块命名。在 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
。
就放置位置而言 - lib
中的任何 .ex
文件都可以,因为 elixir 会编译所有这些文件。事实上,您只需将代码粘贴到 router.ex
中即可快速进行测试。按照惯例,文件名应该跟在模块名称之后,所以 HelloWeb.BackgroundJob.Plug
应该位于 lib/hello_web/background_job/plug.ex
.
是的,我理解你的困惑。
可以在指南中更清楚地解释它。
如果将模块名称传递给作用域,传入的模块名称将作为作用域中所有模块的前缀。
例如,假设您传入的模块名称是 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
方法和其他路线,这些方法和其他路线对于传达想法不是必需的。
希望对您有所帮助。
我目前正在学习 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 几乎一无所知,所以这可能是显而易见的事情,但我真的在那里呆了几个小时。谁能帮我找出该代码的放置位置?
欢迎使用 Whosebug。
你没有发布你遇到的错误,但我猜你的问题是模块命名。在 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
。
就放置位置而言 - lib
中的任何 .ex
文件都可以,因为 elixir 会编译所有这些文件。事实上,您只需将代码粘贴到 router.ex
中即可快速进行测试。按照惯例,文件名应该跟在模块名称之后,所以 HelloWeb.BackgroundJob.Plug
应该位于 lib/hello_web/background_job/plug.ex
.
是的,我理解你的困惑。 可以在指南中更清楚地解释它。
如果将模块名称传递给作用域,传入的模块名称将作为作用域中所有模块的前缀。
例如,假设您传入的模块名称是 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
方法和其他路线,这些方法和其他路线对于传达想法不是必需的。
希望对您有所帮助。