I’m rendering a view but it is throwing error while association loading. Not sure what I’m missing. Been breaking my head but unable to find solution.
Matter of fact it was working fine before with Phoenix 1.3.0
and now run into this problem after upgrading Phoenix to 1.6.15
Error:
[error] #PID<0.11572.0> running PxrfWeb.Endpoint (connection #PID<0.11571.0>, stream id 1) terminated
Server: localhost:4001 (http)
Request: GET /api/v2/media/{media_id}
** (exit) an exception was raised:
** (FunctionClauseError) no function clause matching in Ecto.assoc_loaded?/1
(ecto 3.9.5) lib/ecto.ex:568: Ecto.assoc_loaded?(%{id: nil, name: nil, profile_image_media: nil})
(pxrf 2.0.1) lib/pxrf_web/views/user_view.ex:82: PxrfWeb.UserView.render/2
(pxrf 2.0.1) lib/pxrf_web/views/media_view.ex:321: PxrfWeb.MediaView.render/2
(phoenix_view 2.0.2) lib/phoenix_view.ex:557: Phoenix.View.render_to_iodata/3
(phoenix 1.6.16) lib/phoenix/controller.ex:772: Phoenix.Controller.render_and_send/4
(pxrf 2.0.1) lib/pxrf_web/controllers/media/media_controller.ex:1: PxrfWeb.MediaController.action/2
(pxrf 2.0.1) lib/pxrf_web/controllers/media/media_controller.ex:1: PxrfWeb.MediaController.phoenix_controller_pipeline/2
(phoenix 1.6.16) lib/phoenix/router.ex:354: Phoenix.Router.__call__/2
(pxrf 2.0.1) lib/pxrf_web/endpoint.ex:1: PxrfWeb.Endpoint.plug_builder_call/2
(pxrf 2.0.1) lib/plug/debugger.ex:136: PxrfWeb.Endpoint."call (overridable 3)"/2
(pxrf 2.0.1) lib/pxrf_web/endpoint.ex:1: PxrfWeb.Endpoint.call/2
(phoenix 1.6.16) lib/phoenix/endpoint/cowboy2_handler.ex:54: Phoenix.Endpoint.Cowboy2Handler.init/4
(stdlib 4.1.1) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
user_controller.ex
def show(conn, %{"id" => id}) do
current_user = conn.assigns[:current_user]
user_with_media =
case is_nil(current_user) do
true ->
from(
m in Media,
left_join: u in assoc(m, :user),
left_join: o in assoc(u, :organization),
left_join: om in assoc(u, :profile_image_media),
where: m.id == ^id,
select: %{
id: m.id,
title: m.title,
description: m.description,
user: %{
u
| is_followed: false,
organization: %{ # <--- Not all the keys from the schema are mapped here. Only those necessary.
id: o.id,
name: o.name,
profile_image: %{
id: om.id,
url: om.url,
height: om.height,
weight: om.width
}
}
},
}
}
)
|> Repo.one()
false -> .....
# block of code
end
conn |> render("show.json", user: user_with_media)
end
user_view.ex
def render("show.json", %{user: user}) do
%{
id: user.id,
email: user.email,
first_name: user.first_name,
last_name: user.last_name,
account_type: user.account_type,
username: user.username,
organization:
if Ecto.assoc_loaded?(user.organization) do
render_one(user.organization, OrganizationView, "organization.json", as: :organization)
else
nil
end
}
end
Is it because that I’m not using all the keys from the organization schema? Do I need to have all the key defined here as well inside the controller?