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

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
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
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

Other popular topics Top

JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 53690 245
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
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
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

We're in Beta

About us Mission Statement