Как исключить вложенную модель в кодировке 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