Skip to content

feat: redesign relationship declarations#30

Merged
0x054 merged 1 commit intomainfrom
refactor/backrefs
Apr 27, 2026
Merged

feat: redesign relationship declarations#30
0x054 merged 1 commit intomainfrom
refactor/backrefs

Conversation

@0x054
Copy link
Copy Markdown
Contributor

@0x054 0x054 commented Apr 27, 2026

Description

Redesigns collection relationship declarations so type annotations describe the lazy runtime relationship handle while Field(...) metadata declares relationship behavior. This resolves the BackRef typing issues behind #28 and gives many-to-many relationships the same Field-backed helper pattern.

Closes #28

Changes

  • Add Relation[list[T]] for lazy collection relationship handles and move collection query typing there.
  • Change BackRef() and ManyToMany(...) into public helpers over Field(back_ref=True) and Field(many_to_many=True, related_name=..., through=...).
  • Refactor metaclass relationship detection to use Field(...) metadata as the source of truth, with migration errors for old BackRef[...] and ManyToManyField(...) patterns.
  • Update docs, demos, and relationship tests to the new API.

Bridge and Schema Impact

  • No Rust/Python bridge changes
  • Python model/schema changed
  • Rust core or SQL generation changed
  • src/ferro/_core.pyi updated (if needed)
  • Integration test added first for new behavior

Migration / Breaking Changes

  • No breaking changes
  • Breaking changes included (details below)

Old collection declarations now need to migrate:

  • posts: BackRef[list[Post]] | None = None -> posts: Relation[list[Post]] = BackRef()
  • courses: Annotated[list[Course], ManyToManyField(...)] = None -> courses: Relation[list[Course]] = ManyToMany(...)

Singular reverse relationships continue to use the existing awaitable behavior, e.g. profile: "Profile" = BackRef().

Documentation and Changelog

  • No docs update needed
  • Docs updated (README/docs/inline docs)
  • Changelog entry needed

Related Issues

Closes #28

Test plan

  • uv run pytest -q
  • cargo test
  • uv run ruff check <changed code/test files>
  • uv run ruff format --check <changed code/test files>

Note: uv run mkdocs build --strict still fails on existing strict-doc warnings unrelated to this PR (api/fields.md missing crossrefs, existing guide anchors, and untyped **fields doc warnings).

Made with Cursor

Standardize collection relationships on Relation[list[T]] with Field-backed BackRef and ManyToMany helpers.

Made-with: Cursor
@0x054 0x054 merged commit 911e77d into main Apr 27, 2026
7 checks passed
@0x054 0x054 deleted the refactor/backrefs branch April 27, 2026 14:32
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.

BackRef fields typed as BackRef[T] | None causes false-positive type errors on .all() / .add() / .remove()

1 participant