Ecto 3.12
Last reviewed Oct 25, 2026
Prompt Details
Prompt Composition
3prompts
- Erlang/OTP 29187 lines · 8.9K tokens
- Elixir 1.2051 lines · 1.6K tokens
- Ecto 3.1254 lines · 1.9K tokens
Total292 lines · 12.4K tokens
CWE Coverage
- 20
- 22
- 59
- 78
- 89
- 95
- 116
- 117
- 190
- 204
- 208
- 209
- 214
- 250
- 287
- 295
- 296
- 297
- 298
- 299
- 306
- 307
- 319
- 323
- 327
- 338
- 347
- 352
- 362
- 367
- 379
- 400
- 407
- 427
- 444
- 470
- 494
- 502
- 522
- 532
- 611
- 613
- 639
- 664
- 674
- 732
- 755
- 770
- 772
- 789
- 799
- 807
- 829
- 834
- 862
- 863
- 915
- 916
- 918
- 922
- 942
- 943
- 1284
- 1287
- 1395
Prompt Preview
Apply the Elixir 1.20 and Erlang/OTP 29 prompts first. These rules cover Ecto 3.12 with Ecto SQL 3.12 and the Postgrex driver: schemas, changesets, queries, repositories, transactions, tenancy, connections, and migrations.
Changesets and schema fields
- Give
cast/4a literal list of the fields each form or endpoint may set. Never build that list fromMap.keys(params),__schema__(:fields), or anything else the request controls. - Set owner, tenant, role, price, balance, and approval fields from the authenticated context after authorization, never from params.
change/2,put_change/3,force_change/3, andput_assoc/4don't filter or cast, so keep request data out of them. - Declare fields fixed after creation, such as
tenant_idandowner_id, withwritable: :insert, and database-maintained fields withwritable: :never; Ecto then leaves them out of updates and upserts. For fields maintained by application code, use the cast allowlist and authorize each server-side change;:neveralso prevents trusted application writes.update_all/3doesn't consult:writable, so scope those queries yourself. - Mark secret-bearing fields
redact: trueso schema and changeset inspection hides them. It doesn't touch SQL log parameters or telemetry metadata. - Cast nested data with
cast_assoc/3orcast_embed/3and a dedicated:withchangeset per child type, after preloading only the children the user may edit. Withon_replace: :deleteor:delete_if_exists, a child left out of the params is deleted, and a:drop_paramlets the request choose which children