17

I've just started working on my first Phoenix app, and the issue is that I have some common lines of code in every action in my controller, that I would like to separate out. They fetch data from multiple Ecto Models and save them to variables for use.

In Rails, I could simply define a method and call it using before_filter in my controller. I could access the result from an @variable. I understand that using Plugs is the key but I'm unclear on how to achieve this, more specifically:

  • Accessing the request params from a Plug
  • and making the variables accessible in actions

As a reference, this is the rails version of what i'm trying to do:

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

Thanks!

4

2 回答 2

25

您确实可以使用 aPlugPlug.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

请记住在您的操作插件之前添加插件声明,因为它们是按顺序执行的。

于 2015-06-20T22:20:25.220 回答
3

作为评论更好,但我缺乏代表;使用当前版本的 Phoenix(1.3.4,2018 年 8 月),如果您使用最佳答案的代码,您只想做plug :store_something:不要使用plug :action因为它是多余的。这些操作将在您列出的插件之后运行。

如果你包括在内plug :action,你会得到(Plug.Conn.AlreadySentError) the response was already sent,因为动作会运行两次,凤凰会生你的气。

于 2018-08-17T17:32:29.410 回答