Back to Start Page
The belongsTo relation
With the belongsTo relation a record from a parent table can be linked to a record of a child table, but not excusively. This may be useful e.g. to assign a record to a predefined type, or group.
In our library example we will add the ability to assign a recommended age-group to each book. These age groups can be pre-defined and set in a table named “Agegroups”. Each book will belong to exactly one agegroup (or none!)
Todo Cheat Sheet
- Required: a parent table and a child table
- Create a model for the child table with list and form
- Add a field named: [childModelName]_id to the parent table
- Extend the parent controller with relation behaviour
- Extend the parent model with the desired relation definition (hasOne)
- Define the details of how to handle the relation in the config_relation.yaml in the parent controller
- Use a Partial widget to include the child fields/forms into the parent form
In the library example used in this wiki, the parent will be the book table, the child table is a description table where a single description (a record) can be linked to exactly one book.
What it will look like
This is the parent form book embedding the related child field called Record finder where the selected agegroup is displayed:
By clicking on the icon at the right of the field (the three lines with a dot at the left) the Record finder dialog opens, where one item can be selected.
Preparation
Prerequisites are
- an installed builder plugin
- any source code editor or e.g. the Developer Tools plugin with built-in Code editor like to be seen on the screenshoots
Required skills
- how to work with builder
- how to create a plugin with builder
- how to create tables and forms with builder
Preparations
- a parent table to embed a relation to a child table
- a child table for the items out of which a single one can be choosen for a parent record
Step 1: Have the child table prepared
First thing is to prepare a child table holding all the information required. Important is one field that is intended to be the one displayed later at the parent form. In our library example it is the field named title.
Step 2: Create the model
Next step is to create the model for this table. This can be done by the side menu models and create. The model name should be in singular form, capital first letter. The model in the library example is called Agegroup.
In the model can be defined which table columns are to be displayed in list view…
… and what the form to edit data will look like:
Step 3: Sidemenu
To create a side menu for a table (list view to be precise) a controller is required. On the other hand creating the controller a side menu can be optionally entered.
So it's necessary to create the menu first, then the controller and then go back again to the menu and add the reference to the controller. Or - the more convenient way - to edit the name of the controller to create in advance.
The controller is to edit in the URL line including the path. In the library example this will be pds/library/agegroups
Step 4: Create the controller
The controller tells OctoberCMS how to handle data. By convention the name of the controller is the name of the table (plural). The related model is the one created before (Agegroup in our example) and the side menu entry is prepared too.
Step 5: Define the type of relation
The type of the needed relation has to be defined - as usual - in the parents model php file. This file has been created by the Builder plugin (see step 2) and located in the plugins models directory.
In the library example this is /pds/library/models/Book.php
The code to add the relation to the model is in the example:
<?php ... public $belongsTo = [ 'agegroup' => ['Pds\Library\Models\Agegroup'] ]; ...
Where
- 'agegroup' is the reference to address the child model as a variable (from the parent),
- 'Pds\Library\Models\Agegroup' is the path to the child model to be related and embedded in the parent form and list
Step 6: Add the related field to the parent table
Unlike the hasOne and hasMany relation the belongsTo relation requires to change the parent table.
To be exact, in the parent table a field is required to hold the id of the related child record.
By default October assumes the name of this field as merging the name of the reference to the child model trailed by '_id': [child model reference]_id.
In our example the name of this field will be agegroup_id
If, because of any reason, the key field in the parent table cannot be named in the pattern of [child model reference]_id the key name has to be defined in the definition of this relation within the parent model (step 5). In our example this could be like:
<?php ... public $belongsTo = [ 'agegroup' => ['Pds\Library\Models\Agegroup', 'key' => 'age_id'] ]; ...
In this case the field in the parent table has to be named age_id.
Step 7: Add related fields to form and list
The final step is to add a field to the parent form view, where the related data can be selected and a column to the list view.
For the form view and the belongsTo relation either a Record finder widget or a Relation widget (which appears as dropdown for a belongsTo relation) can be used. The Record finder gives a more convenient way to select a record, especially if the child table holds a lot of records. If there are only a few to expect in the child table the Relation widget is a good choice too.
Anyhow, if the Record finder is the preferred choice, the most important thing to define ist the List configuration (see the property box at the right in the picture below). Here a reference to the list view of the child model is required. In the library this is $/pds/library/models/agegroup/columns.yaml.
If for some reason the definition of the child list view is not suitable for the Record finder - for example if there are too many columns defined that are not of essence for the selection of a related record - another list view can be defined in the child model. For example to hold only the columns needed. Let's call this additional view columns_finder.yaml. Then the reference has to be $/pds/library/models/agegroup/columns_finder.yaml