Use when validating and casting data with Ecto changesets including field validation, constraints, nested changesets, and data transformation. Use for ensuring data integrity before database operations.
View on GitHubTheBushidoCollective/han
jutsu-ecto
January 24, 2026
Select agents to install to:
npx add-skill https://github.com/TheBushidoCollective/han/blob/main/jutsu/jutsu-ecto/skills/ecto-changesets/SKILL.md -a claude-code --skill ecto-changesetsInstallation paths:
.claude/skills/ecto-changesets/# Ecto Changesets
Master Ecto changesets to validate, cast, and transform data before database operations.
This skill covers changeset creation, validation, constraints, handling associations,
and advanced patterns for maintaining data integrity.
## Basic Changeset
```elixir
defmodule MyApp.User do
use Ecto.Schema
import Ecto.Changeset
schema "users" do
field :name, :string
field :email, :string
field :age, :integer
timestamps()
end
def changeset(user, params \\ %{}) do
user
|> cast(params, [:name, :email, :age])
|> validate_required([:name, :email])
end
end
# Usage
changeset = MyApp.User.changeset(%MyApp.User{}, %{name: "John", email: "john@example.com"})
```
Changesets filter and validate parameters before they're applied to a struct.
The `cast/3` function specifies which fields can be changed, and `validate_required/2`
ensures specific fields are present.
## Creating and Validating Changesets
```elixir
defmodule MyApp.Person do
use Ecto.Schema
import Ecto.Changeset
schema "people" do
field :first_name, :string
field :last_name, :string
field :age, :integer
timestamps()
end
def changeset(person, params \\ %{}) do
person
|> cast(params, [:first_name, :last_name, :age])
|> validate_required([:first_name, :last_name])
|> validate_number(:age, greater_than_or_equal_to: 0)
end
end
# Create changeset
changeset = MyApp.Person.changeset(%MyApp.Person{}, %{first_name: "Jane"})
# Check validity
changeset.valid? # false, last_name is missing
# Access errors
changeset.errors
# [first_name: {"can't be blank", [validation: :required]},
# last_name: {"can't be blank", [validation: :required]}]
```
The `valid?` field indicates whether the changeset has any errors. The `errors`
field contains a keyword list of validation failures with error messages and metadata.
## Inserting with Changesets
```elixir
person = %MyApp.Person{}
changeset = MyApp.Person.changeset(person, %{
firs