lorenzomar

lorenzomar

What is the correct way to re-execute validation on a Ecto Schema?

Hi there!
I’m in the situation where I’m receiving a struct which is also an Ecto Schema (wich embedded_one/many other schemas). To be more precise it is a Commanded command.
Sometimes I may not be in control of how the command was built before dispatching it so I would implement a middleware that validate the command before and pass to the next layer only if everything is ok.

Passing the command to the changeset function doesn’t work since it is not a map (itself or the embedded structs).

Currently I implemented a changeset function like this:

defmodule MySchema do
   ....

   def changeset(%__MODULE__{} = schema, %__MODULE__{} = attrs) do
      changeset(schema, Map.from_struct(attrs))
   end

   def changeset(%__MODULE__{} = schema, attrs) do
      # all changeset stuff: cast, validate, ...
   end
end

All the embedded schemas implement a changeset like that. In this way it recursively transform a struct in a map before executing real changeset functionalities.

It works, but it seems like a lot of work.

Any suggestion? Do you know any better approach? maybe can I approach things differently?

Any help is really welcome.

Thanks!

First Post!

LostKobrakai

LostKobrakai

What you’re running into is twofold.

Ecto.Changeset.cast doesn’t allow non map inputs. That’s by design because cast is meant to deal with external input – as in having uncontrolled values, unknown types of value represenation and such. Stuff like json or form input. When you got a struct that’s very unlikely external input like that anymore. There are other API more suited for the job like put_change/3 or change/2.

The other part is that changeset validations only validate changes, not existing values. You can force values to become changes with e.g. force_change/3 or some other APIs can also optionally force changes on a changeset.

Generally I’d however wonder why you’re validating things in the middle of handling a command and not at creation. A command should likely adhere to a contract shared between parties to be enforced at creation time.

Where Next?

Popular in Questions Top

SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
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
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
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

Other popular topics Top

bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
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
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New

We're in Beta

About us Mission Statement