2016-08-25 33 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快速回复!我完全浏览了文档的这一部分。傻我。 –