简体   繁体   中英

What is a changeset in phoenix elixir

I'm having problem understanding the changeset in model. What it does? Can we have more than one changeset in a single model? eg one for create and another for update.

Can someone elaborate in a simple way so it helps other folks coming to Phoenix.

From the documentation :

Changesets allow filtering, casting, validation and definition of constraints when manipulating models..

There is an example of working with changesets in the introductory documentation in the Ecto module. The functions change/2 and cast/4 are the usual entry points for creating changesets, while the remaining functions are useful for manipulating them.

Changesets are used for creating and modifying your models. A changeset is literally a struct that stores a set of changes (as well as the validation rules.) You pass a changeset to your Ecto Repo to persist the changes if they are valid.

The current master branch of Ecto removes an implicit conversion when passing a model to the Repo on update, which means using a changeset the only way to update a model.

From the changelog:

Given a model to Repo.update/2 has been deprecated as it is inneffective and error prone since changes cannot be tracked

In terms of having multiple changesets per model, the answer is certainly yes. A changeset is simply a function. You actually don't even need to put the changeset functions in your models, however that is a common place to put them.

If you require more fields when registering a user than you do updating a user then you can define a register_changeset and a create_changeset with different required fields.

If you are little bit familiar with Rails, ActiveRecord centralizes database access, query generation, and validation in your models, Ecto divides these responsibilities into separate modules.

ActiveRecord methods are executed within the model class or instance, while Ecto expects you to pass a model, query, or changeset to its functions.

Ecto uses the changeset to perform validations, rather than deal with validations inside the model.

Ecto changesets provide both validations and constraints which are ultimately turned into errors in case something goes wrong.

The difference between them is that validations can be executed without a need to interact with the database and, therefore, are always executed before attemping to insert or update the entry in the database.

However, constraints can only be checked in a safe way when performing the operation in the database. As a consequence, validations are always checked before constraints. Constraints won't even be checked in case validations failed.

Let's see an example:

defmodule User do
  use Ecto.Schema
  import Ecto.Changeset

  schema "users" do
    field :name
    field :email
    field :age, :integer
  end

  def changeset(user, params \\ :empty) do
    user
    |> cast(params, ~w(name email), ~w(age))
    |> validate_format(:email, ~r/@/)
    |> validate_inclusion(:age, 18..100)
    |> unique_constraint(:email)
  end
end

In the changeset/2 function above, we define two validations - one for checking the e-mail format and another to check the age - as well as a unique constraint in the email field.

Let's suppose the e-mail is given but the age is invalid. The changeset would have the following errors:

changeset = User.changeset(%User{}, %{age: 0, email: "mary@example.com"})
{:error, changeset} = Repo.insert(changeset)
changeset.errors #=> [age: "is invalid"]

In this case, we haven't checked the unique constraint in the e-mail field because the data did not validate. Let's fix the age and assume, however, that the e-mail already exists in the database:

changeset = User.changeset(%User{}, %{age: 42, email: "mary@example.com"})
{:error, changeset} = Repo.insert(changeset)
changeset.errors #=> [email: "has already been taken"]

Validations and constraints define an explicit boundary when the check happens. By moving constraints to the database, we also provide a safe, correct and data-race free means of checking the user input.

you, can find more details here Ecto Change Set

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM