2015-06-23 14 views
11

我正在關注Phoenix Guide on Plugs以創建我自己的Module Plug,該會話從會話加載當前用戶。當使用插頭模塊時,@user未被分配,但在router.ex中稱爲私人功能時正常工作。從管道插件中調用時,Plug.Conn.assign不工作

這是我web/router

defmodule MyApp.Router do 
    use MyApp.Web, :router 

    pipeline :browser do 
    plug :accepts, ["html"] 
    plug :fetch_session 
    plug :fetch_flash 
    plug :protect_from_forgery 
    plug MyApp.Plugs.User 
    end 

    # Scopes and Routes... 

end 

這是我的模塊(web/plugs/user.ex):

defmodule MyApp.Plugs.User do 
    import Plug.Conn 

    def init(default), do: default 

    def call(conn, default) do 
    user = %{ 
     id:  get_session(conn, :user_id), 
     username: get_session(conn, :username) 
    } 

    assign(conn, :user, user) 

    IO.inspect conn 
    end 
end 

我試圖檢查,看看是否真的是被分配,但它不是:

%Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...}, assigns: %{}, 
before_send: [#Function<1.75757453/1 in Plug.CSRFProtection.call/2>, 
    #Function<1.30521811/1 in Phoenix.Controller.fetch_flash/2>, 
    #Function<0.39713025/1 in Plug.Session.before_send/2>, 
    #Function<1.7608073/1 in Plug.Logger.call/2>, 
    #Function<0.72065156/1 in Phoenix.LiveReloader.before_send_inject_reloader/1>], 
body_params: %{}, 
cookies: .... 

回答

14

Plug.Conn.assign返回修改的連接。由於Elixir中的所有數據都是不可變的,因此無法修改舊的數據。在你的情況下,你扔掉assign的結果,conn仍指向舊的連接。你可能想是這樣的:

conn = assign(conn, :user, user) 

這將重新綁定conn變量指向修改後的連接結構。當然,如果assign(conn, :user, user)是函數中的最後一個表達式,那麼它也會起作用,因爲它的結果將被返回。

+0

我明白了......我想我應該在我進入鳳凰城之前獲得我的Elixir基礎知識。 – Sheharyar

+1

還要注意'IO.inspect'返回它檢查的值,所以'assign(conn,:user,user)|> IO.inspect'也會有效 –