# Relations It's possible to set up relations between tables. We currently support 3 relation types. - **hasOne** - **hasMany** - **manyToMany** Relations are defined in the relations key of a table. ## hasOne relations A table with a hasOne relation means that this table has a field(s) that refers to the identifier(s) of another table. **Example:** ```js kontrl.table({ // Other settings name: "comments", relations: [ // avatar is the name of the relation // avatar_id is the field on this table that refers to a post ID // posts is the table with which we're making a relation kontrl.hasOne("post").fields("post_id").with("posts") ] }); kontrl.table({ // Other settings name: "comments", identifier: ["id"] }); ``` This sets up a relation between users and files where a user has an avatar which is a file. If you want to refer to another field that is not the "id" field. You can also give that field or those fields as a parameter to the with function. ```js kontrl.table({ // Other settings relations: [ kontrl.hasOne("post").fields("post_slug").with("posts", ["slug"]) ] }); ``` In this case avatar_id will refer to the url field of the files table. ## hasMany relations A table with a hasMany relation means that this table has many other fields which refer to this table. **Example:** ```js kontrl.table({ // Other settings name: "posts", relations: [ kontrl.hasMany("comments").with("comments", "post_id") ] }); kontrl.table({ // Other settings name: "comments" }); ``` The above example will give posts a relation comments which will be a list of all comments that have comment.post_id = post.id If you use another key than "id" or you use a composite key, you can give those key/keys as parameters to the with & fields function. ```js kontrl.table({ // Other settings relations: [ kontrl.hasMany("comments").fields(["slug"]).with("comments", ["post_slug"]) ] }); ``` ## Many to many relations A many relation sits between 3 tables. 1. The table with the relation 2. The join table (containg a reference to both tables) 3. The related table All 3 tables will have to be defined in Kontrl but the join table can be hidden. (For more information check the tables section). **Example:** ```js kontrl.table({ // Other settings name: "users", // the first roles is the relation name // the seconds "roles" is the table with which we are joining // users_roles is the join table // user_id is the field on the join table that refers to this table // role_id is the field on the join table that refers to the related table (aka to the roles table) relations: [ kontrl.manyToMany("roles").with("roles").through("users_roles", "user_id", "role_id") ] }); // The users_roles table has a user_id and a role_id field. kontrl.table({ // Other settings name: "users_roles" }); kontrl.table({ // Other settings name: "roles" }); ``` The above code sets up users to have a field roles which has all roles that are defined in the users_roles table. user_id and role_id can also be arrays with composite keys in the above example.