2016-08-25 30 views
1

所以我得到下面的錯誤,因爲我試圖訪問:id密鑰。這裏毫不奇怪。但是,我的實際問題是爲什麼用戶放在:session密鑰內?這個插頭是特定的嗎?我不記得如下圖所示將用戶設置爲密鑰:session插件連接或會話中的KeyError

錯誤:

** (KeyError) key :id not found in: 
%{ 
    session: %ExampleApp.User{ 
    __meta__: #Ecto.Schema.Metadata<:loaded, "users">, 
    email: "[email protected]", 
    first_name: "keith", 
    id: 356, 
    inserted_at: #Ecto.DateTime<2016-08-25 00:56:51>, 
    last_name: "a.", 
    updated_at: #Ecto.DateTime<2016-08-25 00:56:51>, 
    username: "keith" 
    }, 
    view_module: ExampleApp.SessionView, 
    view_template: "show.json" 
} 

查看導致錯誤:

defmodule ExampleApp.SessionView do 
use ExampleApp.Web, :view 

def render("show.json", %{jwt: jwt, user: user, exp: exp}) do 
    %{ 
    jwt: jwt, 
    exp: exp, 
    user: render_one(user, __MODULE__, "show.json") 
    } 
end 

def render("show.json", user) do 
    %{ 
    id: user.id, #<------------------------------------------ HERE 
    username: user.username, 
    last_name: user.last_name, 
    first_name: user.first_name 
    } 
end 

我不得不做以下訪問用戶的信息:

... 

def render("show.json", user) do 
    %{ 
    id: user.session.id, #<------------------------------------------ HERE 
    username: user.session.username, 
    last_name: user.session.last_name, 
    first_name: user.session.first_name 
    } 
end 

這裏的控制器,如果有幫助:

defmodule ExampleApp.RegistrationController do 
use ExampleApp.Web, :controller 

alias ExampleApp.{Repo, User, SessionView} 

def create(conn, %{"user" => user_params}) do 
    changeset = User.new_changeset(%User{}, user_params) 
    case Repo.insert(changeset) do 
    {:ok, user} -> 
     {:ok, jwt, claims} = user |> Guardian.encode_and_sign(:token) 
     exp = Map.get(claims, "exp") 

     conn 
     |> put_status(:created) 
     |> render(SessionView, "show.json", %{jwt: jwt, user: user, exp: exp}) 

    {:error, changeset} -> 
     conn 
     |> put_status(:unprocessable_entity) 
     |> render("error.json", changeset: changeset) 
    end 
    end 
end 

我在這裏做錯了什麼?預先感謝您的幫助。

回答

2

However, my actual question is why is the user placed inside the :session key?

這是因爲render_one試圖猜測你使用通過視圖的名稱的鍵名。在這種情況下,您通過了SessionView,因此用於該模型的密鑰被推斷爲:session。如果你不是希望它是在:user,你可以通過as: :user

def render("show.json", %{jwt: jwt, user: user, exp: exp}) do 
    %{ 
    jwt: jwt, 
    exp: exp, 
    user: render_one(user, __MODULE__, "show.json", as: :user) 
    } 
end 

您可以在documentation for Phoenix.View.render_one/4閱讀更多關於這一點。

...

render_one user, UserView, "show.html" 

...

The underlying user is passed to the view and template as :user , which is inflected from the view name. The name of the key in assigns can be customized with the :as option:

render_one user, UserView, "show.html", as: :data 

...

+0

謝謝@Dogbert快速回復!我完全瀏覽了文檔的這一部分。傻我。 –