How to automatically get an empty list when encoding in Jason schema with unloaded associations?

Suppose I have the following:

defmodule Proj.Lecture do
    schema "lectures" do
       field :title, :string
       field :is_active?, :boolean
       has_many :list_courses, Proj.Course
    end
end

require Protocol
Protocol.derive(Jason.Encoder,
                Syntax.Lectures.Lecture,
                only: [:title, :is_active?,:list_courses,:id])

Suppose an object Proj.Lecture is loaded from the database without the :list_courses attribute loaded. I would like the Jason encoding to give an empty list in this case.

Is there a way to do that ? (with Jason or Poison).

I currently get an exception :
** (RuntimeError) cannot encode association :list_courses from Proj.Lecture to JSON because the association was not loaded.

You should have some place (e.g. a phoenix.view or a function) which applies that assumption. What if later there’s a part in your app which expects courses to be loaded. If you add your logic globally to the json encoding your new code would silently fail.

2 Likes

Indeed. See: https://www.rokkincat.com/blog/2015/03/17/json-views-in-phoenix

1 Like

Well, the idea is to avoid boiler plate code. If some part of my app expect the course to be loaded, then it will be via a query which also loads the courses. When using has_many, the corresponding field is not automatically loaded : you have the flexibility to do it or not. I just wanted to use this flexibility.

Thanks for the link, I will have a look.

If there’s a decision to be made I don’t really see why it would be boilerplate. Associations not being loaded can just as well be an accident as it can be expected, which is why I feel having an explicit place to handle the conversion of unloaded assocs to an empty list is better then just globally expecting unloaded associations are always expected. If you put the logic in a function this would be one additional function call at the places you encode json data.

2 Likes