Requires phx.new, install with mix archive.install hex phx_new
mix phx.new app
Common flags:
- --no-gettext
- --no-html
- --no-webpack
- --no-ecto
- --no-dashboard
# find packages matching "postgres"
mix hex.search postgres
# get package information, including available versions and config for current version
# i.e. Config: {:postgrex, "~> 0.15.9"}
mix hex.info postgrex
- phx_gen_auth code generator for authentication scaffold, includes registration and password resets
- pow authentication and user management library
- bamboo email library
- waffle file upload library with support for ImageMagick and S3 buckets
- absinthe GraphQL library
A schema is a single data mapper for an Ecto repository. This only generates the schema file and the migration for the schema. Use --no-migration to skip generating a migration.
Generates lib/app/foo/bar.ex and a related migration
mix phx.gen.schema Foo.Bar foo_bars name:string
A context includes a schema along with an API boundary, by default with standard CRUD operations.
Generates lib/app/foos/bar.ex, lib/app/foos.ex, and a related migration
mix phx.gen.context Foos Bar bars name:string
Generate everything in the context along with lib/app_web/controllers/bar_controller.ex, lib/app_web/views/bar_view.ex, and template files in lib/app_web/templates/ as well as tests/app_web/bar_controller_test.exs
mix phx.gen.html Foos Bar bars name:string
Generate everything in the context along with lib/app_web/controllers/bar_controller.ex, lib/app_web/views/bar_view.ex, as well as tests/app_web/bar_controller_test.exs. The first invocation will also create lib/app_web/controllers/fallback_controller.ex and lib/app_web/views/changeset_view.ex for default behaviors and helper functions, such as handling JSON responses for errors.
mix phx.gen.json Foos Bar bars name:string
Adding --no-context to phx.gen.html or phx.gen.json will generate only the controller, view, templates, and controller test This can be handy in cases that a context exists and a front end needs to be bolted on.
- :integer
- :float
- :decimal
- :boolean
- :map
- :string
- :array
- :references
- :text
- :date
- :time
- :time_usec
- :naive_datetime
- :naive_datetime_usec
- :utc_datetime
- :utc_datetime_usec
- :uuid
- :binary
- :datetime (alias for :naive_datetime)
- :unique
- redact: true
- default: "default value"
- virtual: true
mix phx.gen.context Foos Bar foo_bars name:string
mix phx.gen.context Fazs Baz faz_bazs name:string foo_bar_id:references:foo_bars
Here foo_bars
and foo_bazs
reference the two table names. foo_bar_id
specifies the column name used to track the relation, which shouldbe the table name, singular, with a suffix of _id. By default, the relation will not work and requires wiring up the two modules. Note: may need to use foreign_key if Ecto has issues resolving the column.
lib/foos/bar.ex
schema "foo_bars" do
field :name, :string
has_one :faz_baz, Baz, foreign_key: :foo_bar_id # add this, can also use has_many
timestamps()
end
Specify the has_one relation. Can use has_many with :faz_bazs, Baz
lib/fazs/baz.ex
schema "faz_bazs" do
field :name, :string
belongs_to :foo_bar, Bar # change this from field :bar_id, :integer
timestamps()
end
@doc false
def changeset(baz, attrs) do
baz
|> cast(attrs, [:name, :foo_bar_id]) # change thisto add :foo_bar_id
|> validate_required([:name])
end
To include the relation, include the ID directly
Fazs.create_baz(%{name: "faz", foo_bar_id: 1}
Given a table of Foos.Bar, to reference the table itself:
belongs_to :parent, Foos.Bar
has_many :children, Foos.Bar, foreign_key: :parent_id
Warning: this does not prevent circular dependencies
Get relations in either direction from within a query
Foos.Bar |> preload(:faz_baz) |> Repo.get!(1)
Fazs.Baz |> preload(:foo_bar) |> Repo.get!(1)
Preload relations after getting results
Fazs.list_faz_bazs() |> Repo.preload([:foo_bar])
bars = Foos.list_foo_bars()
bars |> Repo.preload([:faz_baz])
Getting relational data during inserts is the same way
%Fazs.Baz{}
|> Fazs.Baz.changeset(%{name: "baz", foo_bar_id: 1})
|> Repo.insert!() |> Repo.preload(:foo_bar)
Selecting with a query
Repo.all(from b in Foos.Bar, where: b.id == 1, preload: [:faz_baz])