I get the following error on posting a new customer
- rendering the show action is throwing the error. Show in the controller preloads the association with Repo.preload.
Request: POST /api/v1/customers
** (exit) an exception was raised:
** (JaSerializer.AssociationNotLoadedError) The customer_notes relationship returned %Ecto.Association.NotLoaded{}.
Please pre-fetch the relationship before serialization or override the
customer_notes/2 function in your serializer.
Example:
def customer_notes(model, conn) do
case model.customer_notes do
%Ecto.Association.NotLoaded{} ->
model
|> Ecto.Model.assoc(:customer_notes)
|> MyApp.Repo.all
other -> other
end
end
lib/ja_serializer/relationship.ex:47: JaSerializer.Relationship.get_data/3
lib/ja_serializer/builder/resource_identifier.ex:8: JaSerializer.Builder.ResourceIdentifier.build/3
lib/ja_serializer/builder/relationship.ex:33: JaSerializer.Builder.Relationship.add_data/3
(elixir) lib/enum.ex:1043: anonymous fn/3 in Enum.map/2
(elixir) lib/enum.ex:1387: Enum."-reduce/3-lists^foldl/2-0-"/3
View:
1 defmodule DrdispatchApi.CustomerView do
2 use DrdispatchApi.Web, :view
3 use JaSerializer.PhoenixView
4
5 attributes [:name, :phone1, :phone2, :email, :active, :website, :active]
6 has_many :customer_notes,
7 serializer: DrdispatchApi.CustomerNoteSerializer,
8 include: true,
9 type: "customer-notes"
10 has_many :customer_addresses,
11 serializer: DrdispatchApi.CustomerAddressSerializer,
12 include: true,
13 type: "customer-addresses"
14
15 def customer_addresses(model, conn) do
16 case model.customer_addresses do
17 %Ecto.Association.NotLoaded{} ->
18 model
19 |> Ecto.Model.assoc(:customer_addresses)
20 |> DrdispatchApi.Repo.all
21 other -> other
22 end
23 end
24
25 end
Relevant Controller Code:
4 def create(conn, %{"data" => %{"attributes" => customer_params}}) do
15 changeset = Customer.changeset(%Customer{}, customer_params)
16 IEx.pry
17 case Repo.insert(changeset) do
18 {:ok, customer} ->
19 conn
20 |> put_status(:created)
21 |> render(:show, data: changeset.model) <--- [ERROR]
22 {:error, changeset} ->
23 conn
24 |> put_status(:unprocessable_entity)
25 |> render(DrdispatchApi.ChangesetView, "error.json", changeset: c changeset)
26 end
27 end
28
29 def show(conn, %{"id" => id}) do
30 render(conn, model: Repo.get(Customer, id) |> Repo.preload([:customer_notes, :customer_addresses]))
31 end
Serializer:
1 defmodule DrdispatchApi.CustomerSerializer do
2 use JaSerializer
3
4 attributes [ :id, :name, :phone1, :phone2, :email, :website, :active ]
5
6 def customer_addresses(model, conn) do
7 case model.customer_addresses do
8 %Ecto.Association.NotLoaded{} ->
9 model
10 |> Ecto.Model.assoc(:customer_addresses)
11 |> DrdispatchApi.Repo.all
12 other -> other
13 end
14 end
15 end
The answer was to change the create action to changeset to:
changeset = Customer.changeset(%Customer{customer_addresses: []}, customer_params)