quazar

quazar

How to encode ecto schema with Jason with all fields

How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes. Just want it simple without much config.

@derive {Jason.Encoder, except: [:__meta__, :__struct__]} 

I tried this but it failed when association was not loaded. Is there a way I can specify to encode all attributes of schema and association which are preloaded and drop associations which are not loaded.

Most Liked

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

You’ve tagged this with Phoenix which makes me think you’re doing this in order to render a schema for an API. The suggested approach is to not do this with encoder protocols but rather with JSON views: https://www.rokkincat.com/blog/2015/03/17/json-views-in-phoenix

scooter

scooter

If anyone stumbles across this, the blog post referenced regarding why to use JSON views versus encoder protocols has changed URLs: https://rokkincat.com/blog/2015-03-17-json-views-in-phoenix/

amnu3387

amnu3387

You can define the Jason.Encoder protocol for the structure you want, so that it automatically does that, although I’m not positive this should be done instead of explicitly loading or discarding the fields according to where in the code you’re accessing the records, since this will discard that information always, e.g:

defimpl Jason.Encoder, for: [Your.Module] do
  def encode(struct, opts) do
    Enum.reduce(Map.from_struct(struct), %{}, fn
      ({k, %Ecto.Association.NotLoaded{}}, acc) -> acc
      ({k, v}, acc) -> Map.put(acc, k, v)
    end)
    |> Jason.Encode.map(opts)
  end
end

Notice now that this becomes implicit behaviour whenever Jason’s encode is called on this structure.

Other ways of doing it is to have a function that you call at the end of your load, or explicitly querying with a select, substituting the values explicitly when you don’t need them (this makes it so, that it’s explicit on the code actually running where that step is happening, instead of a catch all) e.g:

YourSchema |> where([ys], ys.id == 1) |> select([ys], %YourSchema{ys | associaton_field: nil}) |> Repo.one
amnu3387

amnu3387

I imagine the reply is meant to @quazar - I said “probably” you shouldn’t use the encoder, but nonetheless using the protocol is the only way to really set “Jason to encode all fields in ecto schema”. I do agree that if it’s in phoenix and you’re using views then it makes sense to use that instead. If not using phoenix, or not wanting to define a jason view, then it’s still better to make it explicit instead of relying on the protocol.

julismz

julismz

Some years later, I solved this just creating a module called jason_encoder.ex on lib/MyApp root folder:

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

  defp sanitize_map(map) do
    map
    |> Map.drop([:__meta__, :__struct__])
    |> Enum.reduce(%{}, fn {key, value}, acc ->
      value =
        case value do
          %Ecto.Association.NotLoaded{} -> nil
          _ -> value
        end

      Map.put(acc, key, value)
    end)
  end
end

And that’s all… No need to do anymore.

Where Next?

Popular in Questions Top

vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
Werner
Hi, I’m using Ubuntu 18.04 and after updating to OTP-24.0 yesterday i have this warning when I run “mix local.hex”: 14:57:30.512 [warn] ...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

Other popular topics Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
326 29600 154
New
dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

We're in Beta

About us Mission Statement