Rendering a view throws error no function clause matching in Ecto.assoc_loaded

Under the hood, embeds_one with block is defining a module containing an embedded_schema call.

The error message is telling you that that module needs to have the Jason.Encoder protocol implemented for it; normally this would be done with the @derive attribute mentioned. The “standard” place to define that attribute would be just before embedded_schema, but embeds_one doesn’t provide an extension point there.

There are two ways to approach this:

  • notice that @derive only needs to appear before defstruct is called in the module - and that happens after the END of the block in embedded_schema. So you can write this (see this thread for more discussion):
    embeds_one :user_selection, UserSelection, on_replace: :delete do
      @derive Jason.Encoder
      field(:has_model, :boolean)
      field(:license, License)
    end
    
  • use the “from the outside” method with Protocol.derive after embeds_one:
    embeds_one :user_selection, UserSelection, on_replace: :delete do
      @derive Jason.Encoder
      field(:has_model, :boolean)
      field(:license, License)
    end
    
    Protocol.derive(Jason.Encoder, UserSelection)
    
    I have not actually tried this.