Если вы немного знакомы с Rails, ActiveRecord централизует доступ к базе данных, генерацию запросов и проверку в ваших моделях, Ecto разделяет эти обязанности на отдельные модули.
Методы ActiveRecord выполняются в классе или экземпляре модели, в то время как Ecto ожидает, что вы передадите модель, запрос или набор изменений его функциям.
Ecto использует набор изменений для выполнения проверок, а не для проверки внутри модели.
Наборы изменений Ecto предоставляют как проверки, так и ограничения, которые в конечном итоге превращаются в ошибки, если что-то пойдет не так.
Разница между ними в том, что проверки могут выполняться без необходимости взаимодействия с базой данных и, следовательно, всегда выполняются перед попыткой вставить или обновить запись в базе данных.
Однако ограничения можно безопасно проверить только при выполнении операции в базе данных. Как следствие, проверки всегда проверяются перед ограничениями. Ограничения даже не будут проверяться в случае неудачной проверки.
Давайте посмотрим на пример:
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
В приведенной выше функции changeset/2
мы определяем две проверки - одну для проверки формата электронной почты, а другую - для проверки возраста, а также уникальное ограничение в поле электронной почты.
Предположим, что электронная почта дана, но возраст указан неверно. Набор изменений будет иметь следующие ошибки:
changeset = User.changeset(%User{}, %{age: 0, email: "[email protected]"})
{:error, changeset} = Repo.insert(changeset)
changeset.errors #=> [age: "is invalid"]
В этом случае мы не проверили уникальное ограничение в поле электронной почты, потому что данные не прошли проверку. Давайте зафиксируем возраст и предположим, однако, что электронная почта уже существует в базе данных:
changeset = User.changeset(%User{}, %{age: 42, email: "[email protected]"})
{:error, changeset} = Repo.insert(changeset)
changeset.errors #=> [email: "has already been taken"]
Когда проверка происходит, проверки и ограничения определяют явную границу. Перенося ограничения в базу данных, мы также предоставляем безопасные, правильные и свободные от гонок данные средства проверки пользовательского ввода.
вы можете найти более подробную информацию здесь Ecto Change Set
person
Subhash Chandra
schedule
01.05.2016