Many to many relation
To build a many-to-many relationship between two models, you need to add the code for the new field to the $model_elements array. Additional settings for the field are provided in the description of the Many to many data type.
For example, we want to link Pre-installed models Pages and Blocks with a many-to-many relationship in order to be able to enable and disable blocks on each specific page.
class Pages extends Model
{
protected $name = 'Pages menu';
protected $model_elements = [
...
['Text blocks', 'many_to_many', 'blocks', ['related_model' => 'Blocks']]
];
}
Run migration from the console or admin panel.
composer mv:migrations
Now in the administrative interface of the Pages model there will be a field for selecting blocks that belong to this model. There is no such field in the Blocks model yet. If we want it to be in the second model, we also add the code to the model file. There is no need to run the migration.
class Blocks extends Model
{
protected $name = 'Text blocks';
protected $model_elements = [
...
['Pages', 'many_to_many', 'pages', ['related_model' => 'Pages']]
];
}
If you need to get records in a template or model by a many-to-many relationship, a special asArrays() method is used.
//Extract a record, an object of the Record class
$page = $mv -> pages -> find(65);
//Or like this
$page = (new Pages) -> find(65);
//Get an array of blocks
$blocks = $page -> asArrays('blocks');
//Array with additional conditions (SQL)
$blocks = $page -> asArrays('blocks', ['active' => 1, 'order->asc' => 'name']);
//Display to screen for verification
Debug::pre($blocks);
When you need to display records taking into account the many-to-many relationship, you can use a special parameter from the Query builder.
//In the Blocks model, we add a new method to get blocks of a specific page
public function getRelatedBlocks($page_id)
{
$rows = $this -> select(['pages->m2m' => $page_id, 'active' => 1));
$html = '';
foreach($rows as $row)
{
$html .= ...
}
return $html;
}
Previous section
Trees