Rails' before_filter 等同于 Phoenix
Rails' before_filter equivalent in Phoenix
我刚刚开始开发我的第一个 Phoenix 应用程序,问题是我在控制器的每个操作中都有一些通用代码行,我想将它们分开。他们从多个 Ecto 模型中获取数据并将它们保存到变量中以供使用。
在 Rails 中,我可以简单地定义一个方法并在我的控制器中使用 before_filter
调用它。我可以从 @variable
访问结果。我知道使用 Plugs
是关键,但我不清楚如何实现这一点,更具体地说:
- 正在从
Plug
访问请求 params
- 并使变量可在操作中访问
作为参考,这是我正在尝试做的 rails 版本:
class ClassController < ApplicationController
before_filter :load_my_models
def action_one
# Do something with @class, @students, @subject and @topics
end
def action_two
# Do something with @class, @students, @subject and @topics
end
def action_three
# Do something with @class, @students, @subject and @topics
end
def load_my_models
@class = Class.find params[:class_id]
@subject = Subject.find params[:subject_id]
@students = @class.students
@topics = @subject.topics
end
end
谢谢!
您确实可以通过 Plug
和 Plug.Conn.assign 实现这一目标。
defmodule TestApp.PageController do
use TestApp.Web, :controller
plug :store_something
# This line is only needed in old phoenix, if your controller doesn't
# have it already, don't add it.
plug :action
def index(conn, _params) do
IO.inspect(conn.assigns[:something]) # => :some_data
render conn, "index.html"
end
defp store_something(conn, _params) do
assign(conn, :something, :some_data)
end
end
请记住在动作插件之前添加插件声明,因为它们是按顺序执行的。
这作为评论更好,但我缺少代表;使用当前版本的 Phoenix(1.3.4,2018 年 8 月),如果您使用顶部答案的代码,您只想做 plug :store_something
: do not use plug :action
因为它是多余的。这些操作将在您列出的插件之后 运行。
如果你包含 plug :action
,你将得到 (Plug.Conn.AlreadySentError) the response was already sent
,因为该动作将 运行 两次,Phoenix 会生你的气。
我刚刚开始开发我的第一个 Phoenix 应用程序,问题是我在控制器的每个操作中都有一些通用代码行,我想将它们分开。他们从多个 Ecto 模型中获取数据并将它们保存到变量中以供使用。
在 Rails 中,我可以简单地定义一个方法并在我的控制器中使用 before_filter
调用它。我可以从 @variable
访问结果。我知道使用 Plugs
是关键,但我不清楚如何实现这一点,更具体地说:
- 正在从
Plug
访问请求 - 并使变量可在操作中访问
params
作为参考,这是我正在尝试做的 rails 版本:
class ClassController < ApplicationController
before_filter :load_my_models
def action_one
# Do something with @class, @students, @subject and @topics
end
def action_two
# Do something with @class, @students, @subject and @topics
end
def action_three
# Do something with @class, @students, @subject and @topics
end
def load_my_models
@class = Class.find params[:class_id]
@subject = Subject.find params[:subject_id]
@students = @class.students
@topics = @subject.topics
end
end
谢谢!
您确实可以通过 Plug
和 Plug.Conn.assign 实现这一目标。
defmodule TestApp.PageController do
use TestApp.Web, :controller
plug :store_something
# This line is only needed in old phoenix, if your controller doesn't
# have it already, don't add it.
plug :action
def index(conn, _params) do
IO.inspect(conn.assigns[:something]) # => :some_data
render conn, "index.html"
end
defp store_something(conn, _params) do
assign(conn, :something, :some_data)
end
end
请记住在动作插件之前添加插件声明,因为它们是按顺序执行的。
这作为评论更好,但我缺少代表;使用当前版本的 Phoenix(1.3.4,2018 年 8 月),如果您使用顶部答案的代码,您只想做 plug :store_something
: do not use plug :action
因为它是多余的。这些操作将在您列出的插件之后 运行。
如果你包含 plug :action
,你将得到 (Plug.Conn.AlreadySentError) the response was already sent
,因为该动作将 运行 两次,Phoenix 会生你的气。