Phoenix JSON-API Serialization с получением Ecto.Association.NotLoaded только в действии show после создания

Я получаю следующую ошибку при публикации нового customer - рендеринг действия show вызывает ошибку. Показать в контроллере предварительно загружает ассоциацию с 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

Вид:

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

Соответствующий код контроллера:

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

Сериализатор:

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

person Richard Holland    schedule 13.11.2015    source источник


Ответы (1)


Ответ заключался в том, чтобы изменить действие создания на набор изменений:

changeset = Customer.changeset(%Customer{customer_addresses: []}, customer_params)

person Richard Holland    schedule 13.11.2015