krut

krut

I am writing an API integration that uses embedded schemas to cast response data before it is used internally. The id fields in the responses are typically integers, and I would like them to convert them to strings.

I could transform these values manually, but there are a number of different responses and schemas, all with the same id format, so I am thinking it could be nice to define a custom type that handles this conversion “behind the scenes”.

I have defined my type as:

defmodule Types.ResponseID do
  @behaviour Ecto.Type
 
  def type, do: :string

  def cast(integer) when is_integer(integer) do
    { :ok, Integer.to_string(integer) }
  end

  def cast(string) when is_binary(string), do: { :ok, string }

  def cast(_), do: :error
end

And my schema:

defmodule Thing do
  use Ecto.Schema

  import Ecto.Changeset

  @primary_key false

  embedded_schema do
    field :id, Types.ResponseID
  end

  def from_response(data) do
    %__MODULE__{}
    |> Ecto.Changeset.cast(data, [:id])
    |> apply_changes()
  end

Which then throws these warnings:

warning: function dump/1 required by behaviour Ecto.Type is not implemented (in module ResponseID)
  lib/types/response_id.ex:1: ResponseID (module)

warning: function embed_as/1 required by behaviour Ecto.Type is not implemented (in module ResponseID)
  lib/types/response_id.ex:1: ResponseID (module)

warning: function equal?/2 required by behaviour Ecto.Type is not implemented (in module ResponseID)
  lib/types/response_id.ex:1: ResponseID (module)

warning: function load/1 required by behaviour Ecto.Type is not implemented (in module ResponseID)
  lib/types/response_id.ex:1: ResponseID (module)

My question - Do I need to add @behaviour Ecto.Type for a custom type in an embedded schema? Or is this a better way to define a custom type for this use case?

I found this comment suggesting that the additional behaviors (e.g. load/dump) are not necessary for custom types in embedded schemas, but I haven’t found any documentation showing an example of how to implement:

Thanks!

Showing Posts 1 to 3

LostKobrakai

LostKobrakai

The callbacks are still required for the behaviour to be correctly implemented, otherwise you’ll get the warnings you see. They’re just not used for fields in embedded schemas.

Given you also have warnings about :embed_as and :equal? you’ll want to implement those as well or use use Ecto.Type instead of @behaviour Ecto.Type to have defaults generated.

krut

krut OP

Thanks! I think use Ecto.Type is what I was looking for here, since I really only need to cast. Warnings are gone and it’s working great :slight_smile:

Aetherus

Aetherus

In Ecto 3.x, you can implement embed_as/1 and return :dump. If you do so, Ecto will call YourCustomType.dump/1 before JSON serialization when saving embedded schema into DB. On the other hand, if embed_as/1 returns :self, then Ecto won’t call dump before JSON serializing an embed.

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New

Other Trending Topics Top

nature
NatureWhistle v0.4.1 is out! :tada: This release is a pretty significant step forward for the project. When I first built NatureWhistle,...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews