Generate Phoenix resources (contexts, schemas, LiveViews, controllers) using mix phx.gen.* commands with best practices. Use when creating new Phoenix resources, contexts, or LiveView components.
This skill helps generate Phoenix resources using built-in generators with proper patterns and best practices.
mix phx.gen.context - Generate a context with schema and migration
mix phx.gen.context Accounts User users name:string email:string:unique age:integer
Generates:
lib/my_app/accounts.exlib/my_app/accounts/user.expriv/repo/migrations/*_create_users.exsmix phx.gen.schema - Schema and migration only (no context)
mix phx.gen.schema Accounts.User users name:string email:string:unique
mix phx.gen.live - Full LiveView CRUD with context
mix phx.gen.live Catalog Product products \
name:string \
description:text \
price:decimal \
sku:string:unique \
in_stock:boolean
Generates:
mix phx.gen.live.component - Standalone LiveView component
mix phx.gen.live.component Components.Modal
mix phx.gen.html - HTML resource with controllers
mix phx.gen.html Blog Post posts title:string body:text published:boolean
mix phx.gen.json - JSON API resource
mix phx.gen.json Shop Product products name:string price:decimal
string - varchar(255)text - unlimited textinteger - whole numbersdecimal - precise decimals (for money)float - floating pointboolean - true/falsedate - date onlytime - time onlydatetime - timestampuuid - UUIDbinary - binary data:unique - adds unique index:redact - marks for redaction in logsname:string:unique:redact - chain modifiers# belongs_to
mix phx.gen.context Blog Post posts \
title:string \
body:text \
user_id:references:users
# Specify custom reference
mix phx.gen.context Comments Comment comments \
body:text \
post_id:references:posts \
author_id:references:users
Accounts, Catalog, BlogUser, Product, Postusers, products, posts# Good: Specific types
price:decimal # For money
published_at:datetime # For timestamps
active:boolean # For flags
# Avoid: Wrong types
price:float # Loses precision for money
published:string # Use datetime or boolean
# Always specify references explicitly
user_id:references:users
# Don't use bare integer for foreign keys
user_id:integer # Missing association metadata
For money fields, update migration:
# Generated
add :price, :decimal
# Best Practice - specify precision
add :price, :decimal, precision: 10, scale: 2
Update schema for validation:
# Add to changeset
|> validate_length(:name, max: 100)
|> validate_length(:email, max: 160)
# List fields with types
name:string
email:string:unique
age:integer
bio:text
admin:boolean
inserted_at:datetime
updated_at:datetime # automatic with timestamps()
# Choose appropriate generator
mix phx.gen.live Accounts User users \
name:string \
email:string:unique \
age:integer \
bio:text \
admin:boolean
# Before running migration, edit it
vim priv/repo/migrations/*_create_users.exs
Add:
# lib/my_app_web/router.ex
scope "/", MyAppWeb do
pipe_through :browser
live "/users", UserLive.Index, :index
live "/users/new", UserLive.Index, :new
live "/users/:id/edit", UserLive.Index, :edit
live "/users/:id", UserLive.Show, :show
live "/users/:id/show/edit", UserLive.Show, :edit
end
mix ecto.migrate
mix phx.gen.live Shop Product products \
name:string \
price:decimal \
sale_price:decimal
Then update migration:
add :price, :decimal, precision: 10, scale: 2, null: false
add :sale_price, :decimal, precision: 10, scale: 2
Add to schema:
deleted_at:datetime
Update migration:
add :deleted_at, :utc_datetime
create index(:products, [:deleted_at])
mix phx.gen.schema Comments.Comment comments \
body:text \
commentable_type:string \
commentable_id:integer
mix phx.gen.live Accounts User users \
organization_id:references:organizations \
name:string \
email:string
Add unique constraint on tenant + field:
create unique_index(:users, [:organization_id, :email])
If you need to rollback:
# Rollback migration
mix ecto.rollback
# Delete generated files manually or use:
mix phx.gen.context --undo Accounts User users
Module already exists:
--merge-with-existing-context to add to existing contextRoutes not working:
Migration fails:
# Skip migration
mix phx.gen.context Accounts User users name:string --no-migration
# Binary ID (UUID)
mix phx.gen.schema Accounts User users name:string --binary-id
# Merge with existing context
mix phx.gen.context Accounts Profile profiles bio:text --merge-with-existing-context
# Specify table name
mix phx.gen.schema Accounts User my_users name:string --table my_users