An edit page featured 3 forms, all bound to the same model. The idea for bringing changesets into Ember occurred to me while I was working on a new client app. Ecto is often confused with Rails’ ActiveRecord, but it isn’t an ORM, and shouldn’t be used like one. This ensures that we catch invalid data in the app layer before insertion into the database. Changes are validated and checked against database constraints (such as uniqueness) before casting. One of the core concepts in Ecto is the changeset - an atomic collection of changes. In Elixir, we use Ecto, a DSL for writing queries and interacting with databases. It turns out whole classes of bugs disappear when embracing immutability and pure functions. That isn’t to say that one is better than the other, but in my experience less unexpected behavior occurs in FP. In fact, I try to use functional approaches wherever possible in JavaScript as well. FP feels more intuitive and less prone to “shoot yourself in the foot” scenarios compared to OOP. I am blown away by how nice it is working with Elixir and functional programming (FP) concepts. The choice of using schemas or not above didn't affect the solution as much as the choice of breaking the registration problem apart.The past month or so, I’ve been working on an Elixir and Phoenix API for a client. However, the most important lesson in this guide is not when to use or not to use schemas, but rather understand when a big problem can be broken into smaller problems that can be solved independently leading to an overall cleaner solution. Otherwise, you can bypass schemas altogether, be it when using changesets or interacting with the repository. The choice of using schemas depends mostly if you want to use the same mapping in different places or if you desire the compile-time guarantees Elixir structs gives you. You can use this technique to validate API endpoints, search forms, and other sources of data. With the schema in hand, we can use Ecto changesets and validations to process the data: fields = changeset = % Registration |> Ecto.Changeset. We used embedded_schema because it is not our intent to persist it anywhere. For such, let's define a schema named Registration that will take care of casting and validating the form data exclusively, mapping directly to the UI fields: defmodule Registration do use Ecto.Schema embedded_schema do field :first_name field :last_name field :email end end The first will cast and validate the external data with its own structure which you then transform and write to the database. One alternative solution is to break the "Database Ecto schema Forms / API" mapping in two parts. If the Profile schema is used for both reading and writing data, it may end-up in an awkward place where it is not useful for any, as it contains fields that map just to one or the other operation. It is not hard to see how we are polluting our Profile schema with UI requirements by adding fields such first_name and last_name. One of such schemas would be: defmodule Profile do use Ecto.Schema schema "profiles" do field :name field :first_name, :string, virtual : true field :last_name, :string, virtual : true. One approach would be to have two schemas, Account and Profile, with virtual fields such as first_name and last_name, and use associations along side nested forms to tie the schemas to your UI. Given the requirements above, how would we implement the Sign Up feature in the backend? Furthermore, you know it would be useful to break the "Sign Up" information across two tables, the "accounts" and "profiles" tables. Although your client is decided on presenting both fields, they are a UI concern, and you don't want the UI to dictate the shape of your data. You know there are a couple problems with this approach.įirst of all, not everyone has a first and last name. Imagine you are working with a client that wants the "Sign Up" form to contain the fields "First name", "Last name" along side "E-mail" and other information. We put emphasis on any because it is a common misconception to think Ecto schemas map only to your database tables.įor instance, when you write a web application using Phoenix and you use Ecto to receive external changes and apply such changes to your database, we have this mapping: Database Ecto schema Forms / APIĪlthough there is a single Ecto schema mapping to both your database and your API, in many situations it is better to break this mapping in two. Maybe one for your database, another for your forms.Īn Ecto schema is used to map any data source into an Elixir struct. Maybe one for reading data, another for writing. As we will see, sometimes the best solution is not to completely avoid schemas, but break a large schema into smaller ones. We will take a look at the role schemas play when validating and casting data through changesets. Settings View Source Data mapping and validation
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |