I have a json field in postgres, but I’d like encoding/decoding to only happen on the client, so the data should just be treated as a string on the server. I’ve tried doing that with the following custom type:
defmodule Backend.Model.Types.VerbatimJson do
@moduledoc """
Stores a value in the db as json, but returns it as binary.
Used for data where we don't need to deserialize it into a map on the server.
"""
@behaviour Ecto.Type
def type, do: :string
# cast is called before dump. in our case we only expect binary strings.
def cast(json_blob) when is_binary(json_blob) do
{:ok, json_blob}
end
def cast(_), do: :error
# load is called when fetching stuff *from* the database
def load(json_blob) when is_binary(json_blob) do
json_blob
end
# dump is called when ecto is saving stuff *to* the database.
def dump(json_blob) when is_binary(json_blob) do
{:ok, json_blob}
end
def dump(_), do: :error
end
The problem is that when using this type in a schema, and trying to save a value, it stores the whole value as a string, defeating the whole point of using the json value type. The only way I’ve gotten it to work is by returning a map from dump
, but I’d like to avoid the whole string -> map conversion altogether and just treat the json string I’m passing as a literal json value.
(How) can I do that?