Back to the Rails application overview
Generate Rails code with aontu templates
Follow a component tree, template markers, emit rules, and replacements from the model to Rails source files.
Rendered from
test/system/rb-solar/doc/rails-code.md
in the engine repository. The model, the generators, the committed
application and the check.sh that renders and validates all
of it are in
test/system/rb-solar/.
The Rails example uses seven Ruby templates and one aontu document to write the application files marked as generated. A template specifies both the output paths and the rules that fill them. Read the model guide first for setup and the entity properties.
Separate instructions from output
Open the routes generator. Lines beginning with #-
contain aontu instructions. Other lines provide Ruby output:
#- @"../model.aon"
#-
#- out: file("config/routes.rb", [
#- [
# Generated by aontu from model.aon. Do not edit.
The import loads model.aon relative to the generator file. file
names one output file, config/routes.rb relative to the output
directory, and its second argument is the list of lines that fill it.
A bare string among them is one line of target text.
Ruby treats every #- line as a comment. This lets the template remain
parseable Ruby, with placeholders where generated values will go.
Check its syntax:
ruby -c gen/routes.rb
A syntax check does not run the template as a Rails application. aontu must first evaluate the marked instructions and substitute model values.
What the tree is
file(name, children) builds one node of a component tree: the
shape a generator runtime writes to disk. folder, line and
content are its neighbours; every prop each one takes is checked at
the call, so a misspelled one is refused rather than dropped.
Each file supplies a name and its lines. The generator writes the target’s text explicitly; aontu knows no languages, and nothing here makes it invent a Rails implementation.
The generator’s import and its own declarations form one document. The
imported file supplies service and entity; the generator adds
out, computed from those values. You evaluate the generator, not
model.aon on its own.
See file
in the function index for the full list and what each one takes.
Follow one value into a route
The root-route rule selects the service’s root value:
#- emit([$.service.root], {
#- match: string
#- replace: ROOT: _
#- body: [
root "ROOT"
#- ]
#- })
emit visits
the selected values and uses the first matching rule.
Here the selection is a one-item list containing "planets#index".
match: string admits that value, _ refers to it, and replace
substitutes it for ROOT in the output line.
Inspect the tree without writing anything:
aontu template gen/routes.rb > work/routes.aon
aontu model get out work/routes.aon
One of its lines is:
root "planets#index"
The other rules iterate over entities to write browser routes, API
routes, and action routes. Replacement names must not overlap: aontu
refuses a table with both COLLECTION and COLLECTION_HELPER.
Produce one file per entity
The Active Record generator builds its files with
emit($.entity, ...). For each matching entity it computes the name
from .id, such as app/models/moon.rb.
Inside that file, a second rule emits the class body. .class is the
current entity’s class name. A nested selection of required fields
writes presence validations:
#- emit(filter(.field, { required:true }), {
#- match: name: string
#- replace: FIELD: .name
#- body: [
validates :FIELD, presence: true
#- ]
#- })
filter selects fields with required: true; the rule reads each
selected field’s name. For Moon, this produces validations for
diameter, id, kind, name, and planet_id.
Write the model files into the Rails application directory:
aontu render gen/model.rb app
aontu render --check gen/model.rb app
The first command writes the files this generator names. The second builds them again and compares their bytes with the files on disk. It does not check files owned by other generators.
Choose the generator for the output
| Generator | Reads | Writes under app/ |
|---|---|---|
routes.rb | Service root, entity paths, and actions | config/routes.rb |
migrate.rb | Ordered entities, fields, and indexes | db/migrate/*_create_*.rb |
seeds.rb | Ordered entities and prepared seed rows | db/seeds.rb |
model.rb | Entity classes, associations, and required fields | app/models/*.rb |
api_base.rb | Error definitions | app/controllers/api/base_controller.rb |
api_controller.rb | Entity fields, paths, parents, and actions | app/controllers/api/*_controller.rb |
ui_controller.rb | Entities and their parents | app/controllers/*_controller.rb |
views.aon | Fields, labels, and route helpers | app/views/*/*.html.erb |
The view generator uses ordinary aontu syntax with ERB lines in backtick strings. The template marker mechanism does not support ERB’s delimited comment syntax, so this generator is an aontu file rather than an ERB template.
Understand the checks’ limits
aontu never parses the target: every line a generator writes is text whose syntax it has not validated. Ruby syntax checks and Rails behaviour tests provide the evidence about that text.
Writing the tree leaves files outside it alone. When a rule is removed or a generated path changes, review and remove the obsolete file yourself. The change-and-check guide shows the complete regeneration loop and a field change to try.