Repository navigation
Conversation
Flo0807
marked this pull request as draft
October 10, 2026 16:30
Base automatically changed from
fix/has-many-select-all-options-query
to
develop
October 10, 2026 16:32
Flo0807
force-pushed
the
feature/no-ecto-outside-adapter
branch
from
October 10, 2026 16:32
d8621ca to
31a8395
Compare
Flo0807
force-pushed
the
feature/no-ecto-outside-adapter
branch
2 times, most recently
from
October 16, 2026 07:19
89e6a36 to
09e171b
Compare
This was referenced Oct 23, 2026
Flo0807
added a commit
that referenced
this pull request
Oct 26, 2026
…eutral-filters-and-metrics Bring in develop through #2338: - Backpex.Metric.data/2 of v0.23 becomes data/3, which also receives the criteria. A metric that still defines data/2 doesn't compile, and Backpex.Resource.metric/5 raises for one that only declares the behaviour. - Boolean filters ignore selected keys without an option, as on develop. - Range filters parse number boundaries on integer fields as integers in condition/4, with the field type from the adapter.
This was referenced Oct 28, 2026
This was referenced Oct 29, 2026
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
- Build queries only in the Ecto adapter - Document the adapter boundary in the v0.23 upgrade guide - Note that only the Ecto adapter calls the query callbacks of filters and metrics - Limit the options to the ids after the options query - Cast searched columns of unknown type to text - Document the form mount, the options of HasMany fields and HasManyThrough in the upgrade guide - Select the options by the primary key of the associated schema - Move the upgrade notes to the v0.24 upgrade guide - Pass the LiveResource to HasMany.before_changeset/6 in the options test - Test every option without a test - Test the options the trimmed fixtures no longer configure - Enable the placeholder function and Number help text tests - Adapt the recording adapter and the BelongsTo form test to the adapter callbacks - Match the struct of a change without __struct__ - Move the upgrade notes to the v0.25 guide - Refer to v0.24 as the previous version in the upgrade guide
Flo0807
force-pushed
the
feature/no-ecto-outside-adapter
branch
from
November 13, 2026 09:46
6c5d154 to
6ca3f2e
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack (merge in this order)
develop← this PRBackpex is Ecto-first, but Ecto leaked into the core: the index view built the metric queries with
Backpex.Adapters.Ecto.list_query/4andEcto.Query, the form view called__struct__and the changeset functions from the adapter config,default_attrs/3and the association fields inspected schemas, BelongsTo, HasMany and HasManyThrough built and ran their own option queries, and the Delete item action matchedPostgrex.ErrorandEcto.ConstraintError. Now only the adapter builds queries, calls the repo and inspects schemas. Everything else goes throughBackpex.Adaptercallbacks, mostly viaBackpex.Resource. Changesets stay the currency of forms.Based on #2337, which this PR moves into the adapter.
New adapter callbacks
metric/5: the data of a metric. The Ecto adapter still callsc:Backpex.Metric.query/3.new_item/2: the item of the:newform.association/2: cardinality, owner key and through associations of an association, fordefault_attrs/3, BelongsTo and HasManyThrough.list_options/4,count_options/4and the optionallist_options_by_key/4: the items an association field can select, with:ids,:search,:offsetand:limit.list_options_by_key/4keeps the index forms of BelongsTo at one query per distinct options query. The Ecto adapter applies:idsafter the:options_query, so the index form of BelongsTo only saves an option of its select, even if the options query ignores or widens (or_where) the query it receives. It matches:idsagainst the primary key of the associated schema, not a hardcoded:id.put_assoc/4: used by the form and index views and HasMany.Other changes
:queryableand the order loses:schema. The Ecto adapter resolves them from the fields.Field.schema/2andField.search_condition/3are optional callbacks that only the Ecto adapter calls.use Backpex.Fieldno longer injects them orimport Ecto.Query.item_queryunder a:custom_alias. Number and Currency did this with their ownsearch_condition/3, which is gone.delete_all/2returns{:error, :foreign_key_violation}.Backpex.Resource.delete_all/4passes it on without broadcasting, and the Delete action shows the existing "used elsewhere" message.LiveResource.search_options/2(was/3) andBackpex.Adapters.Ecto.apply_criteria/4(was/3).test/backpex/adapter_boundary_test.exswalks the AST oflib/and fails on Ecto queries, repo calls,__schema__/__struct__,adapter_config/1, Postgrex orBackpex.Adapters.Ectooutside the adapters. Docs are strings, so mentions there don't count. The query callbacks of filters and metrics are allowed to useEcto.Queryand the repo, as they belong to the Ecto adapter. Run againstdevelop, it reports every leak listed above.:queryableassign, the HasMany options query and the HasManyThrough:associationassign,before_changeseton form mount, search anddelete_all/4.Merged with
develop(v0.23.0)developgained features that built queries or inspected schemas outside the adapter. They keep working through the adapter:options_key/3: a term that changes when the options of an association field may change. HasMany and HasManyThrough load their options again when it changes, e.g. when the:options_querydepends on a value of the form (Load HasMany options again when their options query changes #2329). The Ecto adapter returns the options query; the fields only compare the term and never look into it. Without the callback, the fields load their options once.field_type/2: the primitive type of a field.Backpex.Filters.Rangeuses it viaBackpex.Resource.field_type/2to refuse decimal boundaries of a:numberrange on an integer field, instead of reading the schema.Backpex.Resource.metric/5callsBackpex.Metric.data/2(Let metrics get their data from the assigns of the index view #2347) if the metric implements it, and the adapter otherwise.search_options/2.Merged with
develop(v0.24.0)The relation fields of v0.24.0 check submitted values against their options query and filter the form params with
param_keys/2. Both now go through the adapter:association/2also returns the:related_keythe owner key refers to and the:primary_keyof the related items.list_options/4takes a:keycriterion for:idsand keeps alimitoroffsetof the options query in a subquery, so the check also holds for a limited options query.guides/upgrading/v0.25.md.Not in this PR
assigns.:select,:options_queryanditem_queryoptions and the query callbacks of filters and metrics still take Ecto queries. They're documented as part of the Ecto adapter.NULLS FIRST/LASTnow live in one place in the adapter.Testing
mix testincl.integration_test/1369 passed (167 doctests),mix compile --warnings-as-errors,mix format --check-formatted,mix credoandmix deps.unlock --check-unusedpass. The recording adapter of Test every untested option of LiveResources and fields #2436 delegates the new adapter callbacks, and its BelongsTo form test gets the options from an adapter instead of a repo.develop: 811 tests and 167 doctests (incl.test/doc_test.exsand the adapter boundary test),mix credo,mix docswithout warnings,mix compile --warnings-as-errors --force, Sobelow,mix deps.unlock --check-unusedandmix gettext.extract --check-up-to-datepass.bun run lintpass, including the query count tests for the BelongsTo index forms and for the HasMany options that depend on the form.develop):