Bylaw.Db.Adapters.Postgres.Checks.EctoChangesetCheckConstraints
(bylaw_postgres v0.1.0-alpha.1)
Copy Markdown
View Source
Validates Ecto.Changeset.check_constraint/3 annotations for Postgres checks.
Examples
With a check constraint on users.age, before:
def changeset(user, attrs) do
user
|> Ecto.Changeset.cast(attrs, [:age])
|> Ecto.Changeset.validate_number(:age, greater_than_or_equal_to: 13)
endThe database still protects the invariant, but a constraint failure may reach
callers as a database error instead of a changeset error attached to :age.
After, annotate the changeset with the matching check constraint:
def changeset(user, attrs) do
user
|> Ecto.Changeset.cast(attrs, [:age])
|> Ecto.Changeset.validate_number(:age, greater_than_or_equal_to: 13)
|> Ecto.Changeset.check_constraint(:age, name: :users_age_check)
endEcto can turn the database rejection into a normal changeset error.
Notes
The check skips dynamic cast or change field lists, check expressions
without catalog column metadata, and constraints whose columns cannot be
mapped to Ecto schema fields.
Options
The check discovers compiled Ecto schemas through reflection, parses source
files for conservative changeset candidates, and only requires
check_constraint/3 when Postgres can associate a check constraint with
fields that a candidate casts. Dynamic cast/change field lists and check
expressions without catalog column metadata are skipped for v1.
Pass paths: [...] so Bylaw can parse source AST for user-defined changeset
functions:
{Bylaw.Db.Adapters.Postgres.Checks.EctoChangesetCheckConstraints,
paths: ["lib/my_app"]}When the repo can report config()[:otp_app], schema module discovery is
derived from it. Use schema_modules: [...] when the check should inspect an
explicit set of schemas instead:
{Bylaw.Db.Adapters.Postgres.Checks.EctoChangesetCheckConstraints,
paths: ["lib/my_app/catalog"],
schema_modules: [MyApp.Catalog.Product, MyApp.Catalog.Price]}Use rules: [...] to scope the Postgres constraints considered by the check:
{Bylaw.Db.Adapters.Postgres.Checks.EctoChangesetCheckConstraints,
paths: ["lib/my_app"],
rules: [
[
only: [schema: "public"],
except: [[table: "legacy_products", constraint: "legacy_price_check"]]
]
]}Usage
Add this module to the checks passed to
Bylaw.Db.Adapters.Postgres.validate/2. See the
README usage section for the full ExUnit setup.
Summary
Functions
Implements the Bylaw.Db.Check validation callback.
Types
Functions
@spec validate(target :: Bylaw.Db.Target.t(), opts :: check_opts()) :: Bylaw.Db.Check.result()
Implements the Bylaw.Db.Check validation callback.