caslu
Hello guys! I’m developing an API only Phoenix project for pet donations, and at the moment i have the following schemas:
- User schema:
schema "users" do
field :name, :string
field :email, :string
field :bio, :string
field :avatar, :string
field :website, :string
field :phone, :string
field :social_links, {:array, :string}
field :roles, {:array, Ecto.Enum}, values: [:ADOPTER, :DONOR]
has_many :pets, Announcements.Pet, foreign_key: :owner_id
timestamps(type: :utc_datetime)
end
- Pet schema:
schema "pets" do
field :name, :string
field :size, :decimal
field :bio, :string
field :photos, {:array, :string}
field :age, :integer
field :gender, Ecto.Enum, values: [:MALE, :FEMALE]
field :species, Ecto.Enum, values: [:DOG, :CAT]
field :vaccinated, :boolean, default: false
field :dewormed, :boolean, default: false
field :neutered, :boolean, default: false
field :disability, :boolean, default: false
field :pedigree, :boolean, default: false
field :weight, :decimal
belongs_to :user, Accounts.User, foreign_key: :owner_id
belongs_to :breed, Announcements.Breed, foreign_key: :breed_id
timestamps(type: :utc_datetime)
end
- and the Breed schema:
schema "breeds" do
field :name, :string
field :temperaments, {:array, :string}
has_many :pets, Announcements.Pet, foreign_key: :breed_id
timestamps(type: :utc_datetime)
end
As you can see, the relations above are pretty simple actually, users can own many pets announces and therefore each pet announcement belongs to a user, each pet belongs to a breed, and this specific breed can own a lot announcements, so another many to one relationship.
The problem is around pets and breeds, when i insert a pet, breed or user everything looks fine, but when i trigger the show action on pets_controller the Jason complains that it’s unable to encode because of NotLoaded Association. I know there's questions similars and i know i could preloadthe breeds association with pets, but the weird fact for me is that Jason does not complain if i don't preload the:userassociation, and when i triggershowaction ofuser_controller` Jason does the encoding pretty well even with not loaded pet associations, so what i want to understand is why this error is happening with only one association.
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #phoenix_html
- #iex
- #graphql
- #ai
- #genstage
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex











First 10 of 18 Posts
cmo
I think you’ll need to show the code that is loading stuff from the database.
03juan
This sounds like the same kind of issue I answered in another post recently. Ecto `change/2` preloading associations? - #3 by 03juan
Basically when you build a new struct, the change function replaces
NotLoadedwith the respective “empty” value,nilforbelongs_toandhas_oneor[]forhas_many, specifically for things like forms so you don’t have to do it manually. But when you’re loading an existing record from the db you have to preload the association to replace theNotLoadedstruct before you access the data.Since you mention Jason I assume you’re setting up your own api controller. If you want to send the base struct without having to preload, the you can either
@derive {Jason.Encoder, except: [:user, :breed]}above theschema "pets"declaration, which will always strip out those keys when serialising, or manually define your own protocol implementation so you can send the nested user and breed when they’re preloaded or exclude those keys when their values areNotLoaded.See the
defimpl Jason.Encoderexample and let us know how it goes.caslu
Just a regular
Repo.get!function is enough to trigger the errorcaslu
I’ve tried the derive on pets schema but had not successful at all, Jason still complained about the Not Loaded Association
03juan
I’m sorry, my code is actually incomplete, you also have to exclude the
:__meta__key or it fails with** (RuntimeError) cannot encode metadata from the :__meta__ field. However it should have removed the other keys and not complain aboutNotLoaded.Please post the code for your derivation and the output from an iex session showing the failure, or how you’re using the struct in your controller.
Can’t help any more than this without it…
Does
Repo.get!(Announcements.Pet, pet_id)error in iex?dimitarvp
You likely have this somewhere in your controller(s)?
caslu
It doesn’t because the problem is not with Ecto, just related, the problem is when Jason tries to encode it, at the moment my code snippet of
pet schemais just like that:Even with the @derive clause, Jason seems just to ignore, don’t know why, the error remains the same:
caslu
Don’t mate, the
showaction ofpet_controllerlooks just like the phoenix auto generate:And the
Announcements.get_pet!/1is just aRepo.get!/1callD4no0
First of all, ideally you should have a render file where you decide what shape the return will have, it should look the following (this one was generated using
mix phx.gen.json Accounts User users name:string age:integer):There you can dictate what you render, it also decouples your controller from your schema.
As for error you are getting, you cannot render associations that are not preloaded. There are 2 options of doing that:
Repo.preload/3: Ecto.Repo — Ecto v3.14.0Otherwise if you don’t need them, don’t render them.
03juan
Yes it’s because there is a
NotLoadedvalue that you haven’t removed or replaced before Jason tries to encode it.But this is very weird. What does your heex code look like?