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

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
jonnycharles
I’m in search of an Elixir library that offers PDF generation capabilities similar to Ruby’s Prawn. While there have been discussions abo...
New
Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
roeland
Kia ora, We have been using elixir-google-api to connect to Google Drive. However, with the updates to Tesla due to CVEs this is now bro...
New
subsaharancoder
I’ve followed the Phoenix LiveView file upload code here Uploads — Phoenix LiveView v1.0.0-rc.7 and so far everything works just fine wit...
New
mohsen
I’m using an Umbrella project for a Phoenix application, and I want to have one Ecto Repo and one PostgreSQL database shared by all apps....
New
jaybe78
Hello, I’m developing a online persistent chat system (what’s app) like using elixir/dynamodb/aws for a mobile app(flutter). The diffic...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
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
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews