So I do not know where does this error originated. I know this error is repeated but please help me.
Successfully call a get user but after that gets a stacktrace below
[debug] QUERY OK source="users" db=0.3ms
SELECT u0."id", u0."email", u0."password_hash", u0."first_name", u0."last_name", u0."inserted_at", u0."updated_at" FROM "users" AS u0 WHERE (u0."id" = $1) [10]
[debug] QUERY OK source="rooms" db=1.1ms decode=0.7ms queue=0.2ms
SELECT r0."id", r0."name", r0."topic", r0."inserted_at", r0."updated_at", u1."id" FROM "rooms" AS r0 INNER JOIN "users" AS u1 ON u1."id" = ANY($1) INNER JOIN "user_rooms" AS u2 ON u2."user_id" = u1."id" WHERE (u2."room_id" = r0."id") ORDER BY u1."id" [[10]]
So my stacktrace:
[error] #PID<0.527.0> running SlickWeb.Endpoint (cowboy_protocol) terminated
Server: localhost:4000 (http)
Request: GET /api/users/10/rooms
** (exit) an exception was raised:
** (Protocol.UndefinedError) protocol Enumerable not implemented for %Slick.Accounts.User{__meta__: #Ecto.Schema.Metadata<:loaded, "users">, email: "j@safgjot.com", first_name: "jheccfrey", id: 10, inserted_at: ~N[2018-10-14 06:22:53.773384], last_name: "sajcdaot", password: nil, password_hash: "$argon2i$v=19$m=65536,t=6,p=1$6tZZ8+mIXdkUTX/0Jf6DlQ$8Ln8CdB5DmMZO+kChdeNniuFuNwGbAjWM1u/a2Mz/Ig", rooms: [], updated_at: ~N[2018-10-14 06:22:53.773397]}. This protocol is implemented for: DBConnection.PrepareStream, DBConnection.Stream, Date.Range, Ecto.Adapters.SQL.Stream, File.Stream, Function, GenEvent.Stream, HashDict, HashSet, IO.Stream, List, Map, MapSet, Postgrex.Stream, Range, Stream
(elixir) /home/vagrant/2018-09-24_12-39-03/scripts/elixir/deb/elixir_1.7.3-1/lib/elixir/lib/enum.ex:1: Enumerable.impl_for!/1
(elixir) /home/vagrant/2018-09-24_12-39-03/scripts/elixir/deb/elixir_1.7.3-1/lib/elixir/lib/enum.ex:141: Enumerable.reduce/3
(elixir) lib/enum.ex:2979: Enum.map/2
(slick) lib/slick_web/views/user_view.ex:27: SlickWeb.UserView.render/2
(phoenix) lib/phoenix/view.ex:399: Phoenix.View.render_to_iodata/3
(phoenix) lib/phoenix/controller.ex:729: Phoenix.Controller.__put_render__/5
(phoenix) lib/phoenix/controller.ex:746: Phoenix.Controller.instrument_render_and_send/4
(slick) lib/slick_web/controllers/user_controller.ex:1: SlickWeb.UserController.action/2
(slick) lib/slick_web/controllers/user_controller.ex:1: SlickWeb.UserController.phoenix_controller_pipeline/2
(slick) lib/slick_web/endpoint.ex:1: SlickWeb.Endpoint.instrument/4
(phoenix) lib/phoenix/router.ex:275: Phoenix.Router.__call__/1
(slick) lib/slick_web/endpoint.ex:1: SlickWeb.Endpoint.plug_builder_call/2
(slick) lib/plug/debugger.ex:122: SlickWeb.Endpoint."call (overridable 3)"/2
(slick) lib/slick_web/endpoint.ex:1: SlickWeb.Endpoint.call/2
(plug) lib/plug/adapters/cowboy/handler.ex:16: Plug.Adapters.Cowboy.Handler.upgrade/4
(cowboy) /home/hei/Desktop/elixir/slick/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4
The function where the error points out:
def rooms(conn, _params) do
current_user = Slick.Guardian.Plug.current_resource(conn)
rooms = Slick.Accounts.get_user_rooms(current_user.id)
render(conn, "rooms.json", %{rooms: rooms})
end
UserView Module uses RoomView
defmodule SlickWeb.UserView do
use SlickWeb, :view
alias SlickWeb.UserView
...omitted
def render("rooms.json", %{rooms: rooms}) do
%{data: render_many(rooms, SlickWeb.RoomView, "room.json")}
end
end
RoomView Module:
defmodule SlickWeb.RoomView do
use SlickWeb, :view
alias SlickWeb.RoomView
...omitted
def render("room.json", %{room: room}) do
%{id: room.id,
name: room.name,
topic: room.topic}
end
end
So what I’m trying to do is preload the association of users and display the associated entity to json which will be consumed by a React client
The query below works on iex terminal and work as expected that returns a result
def get_user_rooms(id) do
User
|> Slick.Repo.get!(id)
|> Slick.Repo.preload(:rooms)
end
My suspicion regarding this error would be the ViewModule part but I don’t really get it.