Как исключить вложенную модель в кодировке Ecto Poison

У меня есть простая модель (короткая версия):

defmodule MyApp.User do
  use Ecto.Model

  @derive {Poison.Encoder, only: [:id, :name, :email]}
  schema "users" do
    field :name, :string
    field :email, :string
    belongs_to :company, MyApp.Company

Я ожидаю @derive исключить :company ассоциации при попытке кодировать модель, но это не так. Это происходит при использовании сериализатора Guardian:

defmodule MyApp.GuardianSerializer do
  @behaviour Guardian.Serializer

  alias MyApp.Repo
  alias MyApp.User

  def for_token(user = %User{}), do: { :ok, "User:#{user.id}" }
  def for_token(_), do: { :error, "Unknown resource type" }

  def from_token("User:" <> id), do: { :ok, Repo.get(User, id) }
  def from_token(_), do: { :error, "Unknown resource type" }
end

Я не совсем понимаю, что происходит с

def for_token(user = %User{}), do: { :ok, "User:#{user.id}" }

Из того, что я понимаю user = %User{} пытается проверить, является ли объект, заданный в качестве параметра, допустимым User набор изменений верно?

Но вместо этого я получаю эту ошибку:

не может закодировать связь: компания из MyApp.User в JSON, потому что связь не была загружена. Пожалуйста, убедитесь, что вы предварительно загрузили ассоциацию или удалите ее из данных для кодирования

Я не хочу предварительно загружать его, потому что для кодирования потребуется больше зависимостей, что тоже не работает, я бы предпочел игнорировать это.

Почему only парам в @derive не работает и как я могу решить эту проблему?

1 ответ

Я наконец нашел проблему.

В моем проекте было исправление, связанное со старой версией Ecto, здесь вы можете найти обсуждение этого вопроса и предложение по исправлению, которое я использовал здесь

Итак, в основном я уже переопределял Poison.Encoder в другом месте, для всего (я знаю, это довольно плохо, чтобы сделать это, и, как обычно, это было нечто временное...)

defimpl Poison.Encoder, for: Any do
  def encode(%{__struct__: _} = struct, options) do
    map = struct
          |> Map.from_struct
          |> sanitize_map
    Poison.Encoder.Map.encode(map, options)
  end

  defp sanitize_map(map) do
    Map.drop(map, [:__meta__, :__struct__])
  end
end

Удаляя его, с последней версией ecto / poison / phoenix / Вы-имя-это работает как положено.

Большое спасибо за вашу помощь @ Dogbert

Другие вопросы по тегам