sezaru

sezaru

Use Ecto schema directly or convert to a custom struct?

Hello,

I have a question that probably is somewhat opinion-based.

Basically, when you have a schema for some persisted data in your database, do you use it directly in your code or do you convert it to another struct first?

Example

Say, I have a table to store financial data:

schema "candles" do
  field :timestamp, :utc_datetime_usec
  field :open, :decimal
  field :close, :decimal
  field :high, :decimal
  field :low, :decimal
  field :volume, :decimal
end

It’s typespec would be like this:

@type t :: %__MODULE__{
        __meta__: Ecto.Schema.Metadata.t(),
        id: integer | nil,
        timestamp: DateTime.t() | nil,
        open: Decimal.t() | nil,
        close: Decimal.t() | nil,
        high: Decimal.t() | nil,
        low: Decimal.t() | nil,
        volume: Decimal.t() | nil
      }

Normally what I do is create a struct like this in another module:

defmodule Candle do
  defstruct [:timestamp, :open, :close, :high, :low, :volume]
end

And whenever I read from the database, I always convert from the schema to the struct I created, and that struct is what is used in the rest of the program.

Do you think this is necessary or just a waste of CPU cycles? Can you see any advantages/disadvantages from each approach?

Most Liked

Adzz

Adzz

Great question. This is similar to many discussions i’ve had at work in a few teams.

On the surface it seems like that would be extra work for not much gain. Especially as ecto is super flexible, allowing us to define a schema that only use some of the fields on the table, and allowing virtual fields.

However, I too use this approach, with one adjustment; I make the structs embedded schemas so all of them are ecto structs.

Why? So that i have a clear separation between business logic and the database.

I took a while to get used to the approach, it’s not necessary for every application, it adds some overhead.

But if you do it well where the data is stored is an implementation detail, allowing you yo easily pull things out and move them around without touching the domain logic.

I could have domain fields made from several db tables or even from different APIs.

That kind of approach is taking influence from DDD and hexagonal architecture, so could be more pros / cons in that literature.

al2o3cr

al2o3cr

You’ve described what you’re doing, but not why. What advantage were you aiming for when setting up this pattern?

IMO this feels like boilerplate: you’re literally winding up with the same maps modulo a couple keys.

If you were feeling really fancy you could even do it with key-tweaking:

%CandleSchema{timestamp: ..., etc etc}
|> Map.from_struct()
|> Map.drop([:__meta__])
|> struct!(Candle)

Where Next?

Popular in Questions Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
quazar
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...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
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
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
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
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

We're in Beta

About us Mission Statement