examples:builder:hasone_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:hasone_relation [2021/03/26 18:02]
pdsci-admin [Step 1: Add a reference field to the child table]
examples:builder:hasone_relation [2021/03/27 07:54] (current)
pdsci-admin [Step 5: Create the config_relation.yaml controller file]
Line 2: Line 2:
  
 ====== The hasOne relation ====== ====== The hasOne relation ======
-With the //hasOne// relation a record from a child table can be linked to record of a parent table. This may be useful e.g. to extend tables without changing their structure or if different parts of a record requires to be edited separately.\\ + **With the //hasOne// relation a record from a parent table can be linked to exactly one record of a child table without adding a column to the parent table. This may be useful e.g. to extend an existing (parent) table that should not be altered for some reasons.**\\ 
 +\\
 <WRAP tip> <WRAP tip>
 **Todo Cheat Sheet**\\ **Todo Cheat Sheet**\\
-  * Required: a //parent table// and a //child table//  +  * Required: a //**parent** table// and a //**child** table//  
-  * Add a field named [parentModelName]_id to the child table+  * Add a field named: //[parentModelName]_id// **to the child table**
   * Create a model for the child table with list and form   * Create a model for the child table with list and form
-  * Extend the parent tables controller with relation behaviour +  * Extend **the parent controller** with relation behaviour 
-  * Extend the parent model with the desired relation +  * Extend **the parent model** with the desired relation definition (//hasOne//) 
-  * Define the details of how to handle the relation in the config_relation.yaml+  * 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   * Use a //Partial// widget to include the child fields/forms into the parent form
 </WRAP> </WRAP>
  
 +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 ===== ===== What it will look like =====
 This is what a record with an related record will look like in the example by adding a description to a book. In this example the related form was added into an extra tab on the book form with the options to create a new description, to edit or delete an existing description.\\ This is what a record with an related record will look like in the example by adding a description to a book. In this example the related form was added into an extra tab on the book form with the options to create a new description, to edit or delete an existing description.\\
Line 25: Line 26:
   * an installed [[https://octobercms.com/plugin/rainlab-builder|builder plugin]]   * an installed [[https://octobercms.com/plugin/rainlab-builder|builder plugin]]
   * any source code editor or e.g. the [[https://octobercms.com/plugin/indikator-devtools|Developer Tools]] plugin with built-in Code editor like to be seen on the screenshoots   * any source code editor or e.g. the [[https://octobercms.com/plugin/indikator-devtools|Developer Tools]] plugin with built-in Code editor like to be seen on the screenshoots
-  * a database table for records to attach the media to 
-  * a form (at least in backend) to display the media 
-  * some media already uploaded to the media manager or ready to do so 
  
 Required skills\\ Required skills\\
Line 39: Line 37:
  
 ===== Step 1: Add a reference field to the child table ===== ===== Step 1: Add a reference field to the child table =====
-  * In the library example the parent table is //books// (plural).  +  * In the library example the **parent** table is //**books**// (plural).  
-  * According to this the parent model is called //book// (singular).  +  * According to thisthe parent model is called //book// (singular).  
-  * The related child table shall be named //descriptions// and the respective model //description//.\\+  * The related **child** table shall be named //**descriptions**// and the respective model //description//.\\
 For a //hasOne// 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 the example) For a //hasOne// 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 the example)
  
Line 62: Line 60:
 {{:examples:builder:hasone-childmodel-form.jpg?direct&960 |}} {{:examples:builder:hasone-childmodel-form.jpg?direct&960 |}}
 <WRAP clear /> <WRAP clear />
 +\\
 +\\
 +Here is the complete code to copy, the highlighted rows are the lines probably to add, if the controller was already created. Please remember //Pds\Library// is the namespace of this exampe that has to be adapted to your needs!
 +\\
 +<sxh php; highlight: [10,18]>
 +<?php namespace Pds\Library\Controllers;
 +
 +use Backend\Classes\Controller;
 +use BackendMenu;
 +
 +class Books extends Controller
 +{
 +    public $implement = ['Backend\Behaviors\ListController',
 +                         'Backend\Behaviors\FormController',
 +                         'Backend\Behaviour\RelationController']; // this line adds the relation behaviour
 +    
 +    public $listConfig = 'config_list.yaml';
 +    public $formConfig = 'config_form.yaml';
 +    
 +    //add configuration of relation for Books
 +    // this file has to be created then manually inside the
 +    // [namespace]\controllers\[controllername] folder
 +    public $relationConfig = 'config_relation.yaml'; 
 +
 +    public function __construct()
 +    {
 +        parent::__construct();
 +        BackendMenu::setContext('Pds.Library', 'library-main-menu-item');
 +    }
 +}
 +</sxh>
 \\ \\
 ===== Step 3: Extend the parent controller ===== ===== Step 3: Extend the parent controller =====
Line 101: Line 130:
 \\ \\
 ===== Step 4: Announce the relation to the parent model ===== ===== Step 4: Announce the relation to 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. It's only a few lines to add:\\+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. \\ 
 + 
 +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:\\
  
 <sxh php; highlight: [4-6]> <sxh php; highlight: [4-6]>
 <?php <?php
-...+   ...
        
    public $hasOne = [    public $hasOne = [
Line 112: Line 144:
 </sxh> </sxh>
 \\ \\
-In line the variable '$hasOne' is the type of relation, to let OctoberCMS know which relations to take care for in this model.\\ +In line the public variable '$hasOne' is the type of relation, to let OctoberCMS know which relations to take care for in this model.\\ 
-In line 'description' 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 'description' 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.\\ 
-Remember each definition for a relation is a field. So a definition can hold several definitions for relations. Like so:\\+Remember each definition for a relation is like table field. definition can hold several definitions for different relations. Like so:\\
 <sxh php; highlight: [5-9]> <sxh php; highlight: [5-9]>
 <?php <?php
- ...+    ...
        
     // multiple definitions for one type of relation     // multiple definitions for one type of relation
Line 134: Line 166:
 <sxh php; highlight: [4-7]> <sxh php; highlight: [4-7]>
 <?php <?php
-...+    ...
        
     public $hasOne = [     public $hasOne = [
Line 146: Line 178:
 In the controller file (see step 3) we have announced a relation configuration file. This announcement was:\\ In the controller file (see step 3) we have announced a relation configuration file. This announcement was:\\
 <sxh php; highlight: 18; first-line: 17> <sxh php; highlight: 18; first-line: 17>
-...   +<?php    
 +  
 +    ...   
     public $relationConfig = 'config_relation.yaml';     public $relationConfig = 'config_relation.yaml';
-...    +    ... 
 +    
 </sxh> </sxh>
  
Line 167: Line 202:
  
 <sxh yaml> <sxh yaml>
 +...
 +
 description: description:
     label: Description     label: Description
Line 175: Line 212:
         form: $/pds/library/models/description/fields.yaml         form: $/pds/library/models/description/fields.yaml
         list: $/pds/library/models/description/columns.yaml         list: $/pds/library/models/description/columns.yaml
 +
 +...
 </sxh> </sxh>
  
-  * The root entry **description** is the name we will refer to from the book model.\\+  * The root entry **description** is the name we will refer to from the book model (see code: public $hasOne = ['**description**' => ['Pds\Library\Models\...'.\\
   * The item **label:** holds the text for a label for the field 'description'.\\   * The item **label:** holds the text for a label for the field 'description'.\\
   * 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|update|delete' buttons will add the ability to add, edit or delete a description.\\+  * The item **toolbarButtons** with 'create|update|delete' buttons will add the ability to create a new descrptonto edit or delete an existing one.\\
   * 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
 \\ \\