Skip to main content

Relations

The relations block declares foreign-key relationships between entities. Once declared, you can walk them in any query at any depth.

Shape​

"users": {
"relations": {
"<relation-name>": {
"type": "oto | otm | mto | mtm",
"entity": "<target-entity>",
"prototable":"<target-entity>",
"fkfield": "<foreign-key-spec>",
"through": "<junction-table>"
}
}
}
FieldRequiredPurpose
typeyesRelationship type — see Relationships
entityyesTarget entity (the "other side")
prototableyesTarget proto-table name (usually same as entity)
fkfieldyesForeign key spec — format depends on type
throughonly mtmJunction table for many-to-many

fkfield format​

TypeFormatExample
oto, mtolocal_col:remote_col"user_id:id"
otmlocal_col:remote_col"id:user_id"
mtmlocal_col:through_local:through_remote:remote_col"id:user_id:product_id:id"

Examples​

One user → many orders​

"users": {
"relations": {
"orders": {
"type": "otm",
"entity": "orders",
"prototable": "orders",
"fkfield": "id:user_id"
}
}
}

One order → one user (reverse)​

"orders": {
"relations": {
"user": {
"type": "mto",
"entity": "users",
"prototable": "users",
"fkfield": "user_id:id"
}
}
}

Many products ↔ many categories​

"products": {
"relations": {
"categories": {
"type": "mtm",
"entity": "categories",
"prototable": "categories",
"through": "product_categories",
"fkfield": "id:product_id:category_id:id"
}
}
}

The fkfield here reads as: the local table's id column joins to the through table's product_id column; the through table's category_id column joins to the remote table's id column.

Naming relations​

Relation names live in the same namespace as field names within an entity. Pick names that don't collide. If you have a currency column and a currency relation, ONQL will resolve to the relation in projection contexts. Avoid the conflict by renaming one.