Skip to content

Coerce Ecto.Enum search values to their dumped representation#5

Open
Actalab wants to merge 1 commit into
mainfrom
fix/enum-search-value-coercion
Open

Coerce Ecto.Enum search values to their dumped representation#5
Actalab wants to merge 1 commit into
mainfrom
fix/enum-search-value-coercion

Conversation

@Actalab

@Actalab Actalab commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Problem

Filtering on an Ecto.Enum field via q crashes at the adapter. A field like:

field :status, Ecto.Enum, values: [down: 0, up: 1]

filtered with q[status_in][]=up (or through an association, e.g. q[category_status_in][]=published) builds WHERE status = ANY($1) but passes the raw string ["up"]. The column is an integer, so Postgrex raises:

DBConnection.EncodeError: Postgrex expected an integer in -2147483648..2147483647, got "up"

The search builder never applied the field's schema type, so enum values were sent uncast/undumped.

Fix

  • Attribute now carries the resolved schema type — but only when the value needs coercion (i.e. Ecto.Enum). Plain fields keep type: nil and pass through unchanged, so there is no behavior change for string/integer/uuid/etc. columns. The field is hidden from Inspect (@derive {Inspect, optional: [:type]}) so it doesn't leak into output.
  • BuildSearchQuery.coerce_values/2 casts then dumps each value through that type before the query is built ("up":up1). If a value can't be cast to the enum it falls back to the raw value.
  • Where coerces per attribute before delegating to handle_expr.

Works for every Ecto.Enum (direct field or via association), including string-backed enums (dump returns the string).

Tests

  • Unit coverage for coerce_values/2 (enum dump, untyped passthrough, invalid-value fallback).
  • End-to-end test filtering posts by an associated enum (category_status_in) — this reproduces the reported crash and now returns the matching rows.

35 doctests, 107 tests, 0 failures.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant