Bylaw.Db.Adapters.Postgres.Checks.EctoChangesetForeignKeyConstraints
(bylaw_postgres v0.2.0)
Copy Markdown
View Source
Validates Ecto.Changeset.foreign_key_constraint/3 annotations for Postgres FKs.
Examples
With a foreign key on orders.account_id, before:
def changeset(order, attrs) do
order
|> Ecto.Changeset.cast(attrs, [:account_id])
|> Ecto.Changeset.validate_required([:account_id])
endThe database rejects missing accounts, but the caller may see a low-level
constraint error instead of an :account_id changeset error.
After, annotate the changeset with the matching constraint:
def changeset(order, attrs) do
order
|> Ecto.Changeset.cast(attrs, [:account_id])
|> Ecto.Changeset.validate_required([:account_id])
|> Ecto.Changeset.foreign_key_constraint(:account_id)
endEcto can report the invalid relationship through the changeset API.
Notes
The check skips dynamic cast or change field lists and foreign keys whose
columns cannot be mapped to Ecto schema fields.
Options
:validate- explicitfalsedisables this check.:paths- required non-empty list of source paths to parse for changeset functions.:otp_app- OTP app used for compiled schema discovery. When the target repo can reportconfig()[:otp_app], this is inferred.:schema_modules- explicit non-empty list of schema modules to inspect instead of discovering schemas from:otp_app.:rules- optional rule keyword list or non-empty list of rule keyword lists. Rules use only shared scope keys.
This check requires :paths and schema discovery from the target repo's
inferred :otp_app, explicit :otp_app, or explicit :schema_modules, so
bare-module configuration is not valid.
Run globally for discovered schemas:
{Bylaw.Db.Adapters.Postgres.Checks.EctoChangesetForeignKeyConstraints,
paths: ["lib/my_app"]}Run globally for explicit schema modules:
{Bylaw.Db.Adapters.Postgres.Checks.EctoChangesetForeignKeyConstraints,
paths: ["lib/my_app/billing"],
schema_modules: [MyApp.Billing.Invoice, MyApp.Billing.Payment]}Run only for matching rule scopes:
{Bylaw.Db.Adapters.Postgres.Checks.EctoChangesetForeignKeyConstraints,
paths: ["lib/my_app"],
rules: [where: [schemas: ["public"]], except: [[tables: ["events"], columns: ["actor_id"]]]]}The check discovers compiled Ecto schemas through reflection, parses source
files for conservative changeset candidates, and only requires
foreign_key_constraint/3 when a candidate casts the local foreign-key field.
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.