examples:builder:hasmany_relation

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
examples:builder:hasmany_relation [2021/03/27 14:47]
pdsci-admin [Step 5: Create the config_relation.yaml controller file]
examples:builder:hasmany_relation [2021/04/11 19:06] (current)
pdsci-admin [Step 4: Announce the relation to the parent model]
Line 2: Line 2:
  
 ====== The hasMany relation ====== ====== The hasMany relation ======
- **With the //hasMany// relation a record from a parent table can be linked to one or more record of a child table. No changes in the parent table are required. The key(s) to link parent record to child record(s) are stored in the child table. **\\+ **With the //hasMany// relation a record from a parent table can be linked to one or more record of a child table. No changes in the parent table are required. The key(s) to link parent record to the child record(s) are stored in the child table. **\\
 \\ \\
 <WRAP tip> <WRAP tip>
Line 19: Line 19:
 ===== What it will look like ===== ===== What it will look like =====
  
 +This is the parent form //** book **// embedding the related child list //**reviews**// showing all reviews for the displayed book:\\
 +{{:examples:builder:hasmany-child-in-parent-integration.jpg?direct&960 |}}
 +<WRAP clear />
 +\\
 +Additional reviews can be crated with the button //Create Reviews//. By clicking on a row in the reviews table, an existing review can be updated directly. 
 +{{:examples:builder:hasmany-child-in-parent-integration2.jpg?direct&960 |}}
 +<WRAP clear />
 +\\
 ===== Preparation ===== ===== Preparation =====
 Prerequisites are\\ Prerequisites are\\
Line 40: Line 48:
   * the respective **model** is named **//review//**.   * the respective **model** is named **//review//**.
   * The **controller** for the child is named //**reviews**//.\\   * The **controller** for the child is named //**reviews**//.\\
-For a //hasMany// relation the child table requires a field named by the parent model trailed by '_id'. So in this example the required field has to be called 'book_id'. In this field the id of the record of the parent table will be stored. So the field has to be of the same type as the parent id field (integer in this example).\\ +For a //hasMany// relation the **child table** requires a field named by the parent model trailed by '_id'. So in this library example where reviews will be added to books, the required field in the reviews table has to be called 'book_id'. In this field the id of the record of the parent table will be stored. This field has to be of the same type as the parent id field (unsually integer for IDs).\\ 
-So the table definitions for te //hasMany// relation looks pretty much the same like the //hasOne// definition. The difference is, that the //has Many// child table can hold more than one record with the same key to the parent record.\\+The table definitions for the //hasMany// relation looks pretty much the same like the //hasOne// definition. The difference is, that the //has Many// child table can hold more than one record with the same key to the parent record.\\ 
 + 
 +Here is what the libraray example reviews table looks like. Notice the last line where the field //**book_id**// is already defined:\\ 
 +{{:examples:builder:hasmany-review-table.jpg?direct&960|}}
  
 ===== Step 2: Create a model with list and form for the child table ===== ===== Step 2: Create a model with list and form for the child table =====
-Next for the child table (//reviews// in the example) a model (called //Review//)has to be created...\\ +Next child table (//reviews// in the example) and a model (called //Review//) has to be created...\\ 
 +\\ 
 +This is the form for the reviews:\\ 
 +{{:examples:builder:hasmany-review-form.jpg?direct&960|}} 
 +\\ 
 +\\ 
 +This is the list view for the reviews:\\ 
 +{{:examples:builder:hasmany-review-columns.jpg?direct&960|}} 
 +\\
  
 ===== Step 3: Extend the parent controller ===== ===== Step 3: Extend the parent controller =====
Line 66: Line 84:
     public $implement = ['Backend\Behaviors\ListController',     public $implement = ['Backend\Behaviors\ListController',
                          'Backend\Behaviors\FormController',                          'Backend\Behaviors\FormController',
-                         'Backend\Behaviour\RelationController']; // this line adds the relation behaviour+                         'Backend\Behaviors\RelationController']; // this line adds the relation behaviour
          
     public $listConfig = 'config_list.yaml';     public $listConfig = 'config_list.yaml';
Line 84: Line 102:
 </sxh> </sxh>
 \\ \\
-===== Step 4: Announce the relation to the parent model ===== +===== Step 4: Define the relation within the parent model ===== 
-To make the parent model able to work with the relation, the type of the relation, the name of the relation and the child model have to be announced in the parent model. \\ +To make the parent model able to work with the relation, the type of the relation, the name of the relation and the child model have to be defined in the parent model. \\ 
 +\\ 
 +{{:examples:builder:hasmany-relation-definition.jpg?direct&960|}} 
 +<WRAP clear /> 
 +\\
 The required file is placed in plugins /models/ directory. In case of our example the full path is 'pds/library/models/book.php'.\\ The required file is placed in plugins /models/ directory. In case of our example the full path is 'pds/library/models/book.php'.\\
 It's only a few lines to add:\\ It's only a few lines to add:\\
Line 94: Line 115:
    ...    ...
        
-   public $hasOne = [+   public $hasMany = [
         'reviews' => ['Pds\Library\Models\Review']         'reviews' => ['Pds\Library\Models\Review']
    ];    ];
Line 102: Line 123:
 In line 4 the public variable '$hasMany' is the type of relation, to let OctoberCMS know which relations to take care for in this model.\\ In line 4 the public variable '$hasMany' is the type of relation, to let OctoberCMS know which relations to take care for in this model.\\
 In line 5 'reviews' is the name of the relation, which can be used similar to a table field name. The path assigned to the name of the relation is the path to the model of the child table.\\ In line 5 'reviews' is the name of the relation, which can be used similar to a table field name. The path assigned to the name of the relation is the path to the model of the child table.\\
 +By default the key field to look for the records with related IDs will be created by the name of the model trailed by '_id'. In our example this would be 'book_id'.\\
 +\\
 Remember each definition for a relation is like a table field. A definition can hold several definitions for different relations. Like so:\\ Remember each definition for a relation is like a table field. A definition can hold several definitions for different relations. Like so:\\
 <sxh php; highlight: [5-9]> <sxh php; highlight: [5-9]>
Line 170: Line 193:
     label: Reviews     label: Reviews
     view:      view: 
-        form: $/pds/library/models/review/fields.yaml+        list: $/pds/library/models/review/columns.yaml
         toolbarButtons: create|delete         toolbarButtons: create|delete
     manage:     manage:
         form: $/pds/library/models/review/fields.yaml         form: $/pds/library/models/review/fields.yaml
-        list: $/pds/library/models/review/columns.yaml +        
 ... ...
 </sxh> </sxh>
Line 182: Line 204:
   * The item **label:** holds the text for a label for the field 'review'.   * The item **label:** holds the text for a label for the field 'review'.
   /* The **view** segment indicates how the relation will be shown: As a form in our example because there is only one related child record (because of //hasOne//) per parent record.\\ */   /* The **view** segment indicates how the relation will be shown: As a form in our example because there is only one related child record (because of //hasOne//) per parent record.\\ */
-  * The item **toolbarButtons** with 'create|delete' buttons will add the ability to create a new review or to delete an existing oneAn 'update' button is not necessary, because an update/edit form will be opened by ckicking on a row in the review list.+  * The item **toolbarButtons** with 'create|delete' buttons will add the ability to create a new review directly from the book view or to delete existing onesThe 'update' button is not required, because an update/edit form will be opened by ckicking on a row in the review list.
   * The **manage** sections defines how things are displayed when we are searching or editing an entry   * The **manage** sections defines how things are displayed when we are searching or editing an entry
 \\ \\
Line 192: Line 214:
 \\ \\
 \\ \\
-This is the screenshot for the example above:\\ +This is the screenshot for the example above - notice that a definition is already set (see the hasOne example):\\ 
-/* {{:examples:builder:pds_library_controllers_config_relation.yaml.jpg?direct&960 |}} */+{{:examples:builder:hasmany-config-relation.jpg?direct&960|}}
 <WRAP clear /> <WRAP clear />
 \\ \\
Line 208: Line 230:
  
 See this screenshot too:\\ See this screenshot too:\\
-/* {{:examples:builder:pds_library_controllers_config_relation_create3.jpg?direct&960 |}} */+{{:examples:builder:hasmany-relation-partial.jpg?direct&960|}}
 <WRAP clear /> <WRAP clear />
 \\ \\
Line 217: Line 239:
 So we return to Builder > Models > Book > Forms > field.yaml an add a widget //Partial// displaying and managing the created relation.\\ So we return to Builder > Models > Book > Forms > field.yaml an add a widget //Partial// displaying and managing the created relation.\\
 The field name we have to refer to is //**review**// as defined before. The partial to display is the one defined in step 6: //**$/pds/library/controllers/books/_field_reviews.htm**// \\ The field name we have to refer to is //**review**// as defined before. The partial to display is the one defined in step 6: //**$/pds/library/controllers/books/_field_reviews.htm**// \\
-Notice the '$' in front of the path. This tells october to find subpath and file in the plugin folder. +Notice the '$' in front of the path. This tells october to find subpath and file in the plugin folder.\\ 
-/* {{:examples:builder:hasmany-parentform-addpartial.jpg?direct&960 |}} */+\\ 
 +{{:examples:builder:hasmany-relation-partialfield-in-parent-form.jpg?direct&960|}}
 <WRAP clear /> <WRAP clear />
 \\ \\
 Now the form is ready to create, show, edit, delete, link and unlink a record from the child table within/to a record of the parent table. Now the form is ready to create, show, edit, delete, link and unlink a record from the child table within/to a record of the parent table.
 ---- ----