Module: Ruact::ServerFunctions::RouteSource
- Defined in:
- lib/ruact/server_functions/route_source.rb
Overview
Story 9.3 — derives v2 server-function entries from the Rails route table.
The route table is the single source of truth (FR61): every non-GET routed action on a controller that includes Ruact::Server is a callable server function. This module is the route-driven replacement for the v1 registry source consumed by Snapshot — it reads routes, not ‘ruact_action` declarations.
Pure by construction: RouteSource.collect takes the route set and two resolver callables (host predicate + override lookup). The railtie passes the real constant-resolving implementations; unit specs inject lambdas so the derivation table is testable without booting controllers.
## Derivation table (locked, ADR addendum 2026-06-09)
‘js_identifier = lowerCamel(action) + Namespace*(Pascal) + Resource(Pascal)`
-
**Resource word** — singular for the RESTful writes (‘create`/`update`/ `destroy`) and for any member route (path carries `:id`); plural for a custom collection route. Examples: `posts#create` → `createPost`, `posts#publish` (member) → `publishPost`, `posts#publish_all` (collection) → `publishAllPosts`, `resource :session` `#create` →`createSession`.
-
Namespace — PascalCased and inserted between verb and resource (prefix, NOT flat): ‘admin/posts#create` → `createAdminPost`, `admin/reports/posts#create` → `createAdminReportsPost`. Prefixing keeps the merged JS namespace collision-free by construction (a flat scheme would force `admin/posts#create` and `posts#create` to collide).
-
PATCH/PUT — ‘resources` emits both verbs for `update`; they collapse to one entry with `http_method: “PATCH”` (Rails’ primary verb).
Constant Summary collapse
- MUTATION_VERBS =
Verbs that expose a callable server function. GET/HEAD are pages.
%w[POST PUT PATCH DELETE].freeze
- RESTFUL_WRITES =
The RESTful writes whose JS name uses the SINGULAR resource even though ‘create` is technically a collection route.
%w[create update destroy].freeze
- VERB_PRIORITY =
When the same controller#action is routed under several verbs (the ‘update` PATCH/PUT pair), keep the first by this priority.
{ "PATCH" => 0, "PUT" => 1, "POST" => 2, "DELETE" => 3 }.freeze
Class Method Summary collapse
-
.collect(route_set, host_predicate: nil, overrides_for: nil) ⇒ Array<Hash>
Collects v2 mutation entries from
route_set.
Class Method Details
.collect(route_set, host_predicate: nil, overrides_for: nil) ⇒ Array<Hash>
Collects v2 mutation entries from route_set.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/ruact/server_functions/route_source.rb', line 66 def collect(route_set, host_predicate: nil, overrides_for: nil) host_predicate ||= method(:default_host?) overrides_for ||= method(:default_overrides_for) by_key = {} route_set.routes.each do |route| verb = route.verb.to_s next unless MUTATION_VERBS.include?(verb) controller = route.defaults[:controller] action = route.defaults[:action] next if controller.nil? || action.nil? next unless host_predicate.call(controller) key = [controller, action] existing = by_key[key] # PATCH/PUT collapse: keep the higher-priority verb only. next if existing && verb_rank(verb) >= verb_rank(existing["http_method"]) by_key[key] = build_entry(route, verb, controller, action, overrides_for) end entries = by_key.values.sort_by { |entry| entry["js_identifier"] } detect_collisions!(entries) entries end |