Repository navigation
Derive associations from the server schema - #33
Merged
Merged
Conversation
Funicular::Schema.build reads the ActiveRecord reflections of the model
and sends each belongs_to whose foreign key is an exposed attribute.
Model.load_schema defines the reader from it (comment.post) and, for a
conventional foreign key, the inverse has_many on the target
(post.comments), so the client classes need no declarations.
The rules:
- Both ends must be replica models the client carries, matched by class
name. A storage :local or :ephemeral model never takes part, and an
app without the local database derives nothing.
- A derived association yields to a hand-written declaration, to an
attribute, and to a method of the same name, public or private.
- An entry of the model's own schema outranks an inverse derived from
another model, whichever schema arrives first.
- A polymorphic belongs_to and a composite foreign key do not derive.
- The development console says why an association did not derive.
`associations: false` turns the derivation off, a nil value hides one,
and a hand-written { kind:, class_name:, foreign_key: } entry adds one;
Schema.build rejects a malformed entry.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1XudATNo5yA1EwJ8De9KR
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K1XudATNo5yA1EwJ8De9KR
Derived readers now live in a module that each model includes, so a hand-written declaration, an attribute accessor, or a def on the class wins by method lookup in any order. A separate registry records who derived what, which replaces the :derived and :origin special cases. - A schema that loads again retracts what its previous load derived, inverses on other models included, so a changed or removed association no longer leaves a stale reader. - Every association that does not derive, or that another replaces, says why on the development console. - The name check uses method_defined? instead of building method lists. On the Rails side: - A belongs_to to a column other than id, or to a class that does not load, does not derive; the client reader looks the target up by id. - class_name is the class ActiveRecord resolves (Blog::Post), not the raw name. - A hand-written belongs_to must name an exposed foreign key, and associations: takes only false, nil, or a Hash. - Endpoints and Associations share one override merge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013VaokYGa9iWeyJSe6w3EeS
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.
Background
Funicular::Schema.build reads the ActiveRecord reflections of the model and sends each belongs_to whose foreign key is an exposed attribute.
Model.load_schema defines the reader from it (comment.post) and, for a conventional foreign key, the inverse has_many on the target (post.comments), so the client classes need no declarations.
Rules:
associations: falseturns the derivation off, a nil value hides one, and a hand-written { kind:, class_name:, foreign_key: } entry adds one; Schema.build rejects a malformed entry.