В данной статье речь пойдёт об отношениях в базе данных без которых невозможно реализовать структурные данные такие как «каталог товаров», например, где товары должны быть разбиты по категориям.
Для примера создадим новый плагин с помощью Rainlab.Builder:
Создадим для него две таблицы в базе данных _items и _categorys со следующими полями:
Таблица mcmraak_catalog_items (у вас она будет называться по другому, в зависимости от имени автора и названия плагина) будет содержать три столбца:
- id (integer)
- name (string)
- category_id (integer)
Кстати! После создания таблицы в базе данных, в папке с плагином, а точнее в данном случае по адресу /plugins/mcmraak/catalog/updates создаётся миграция. Ведь OctoberCMS создан на базе чудесного Laravel! Вот содержимое данной миграции:
builder_table_create_mcmraak_catalog_items.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?php namespace Mcmraak\Catalog\Updates; use Schema; use October\Rain\Database\Updates\Migration; class BuilderTableCreateMcmraakCatalogItems extends Migration { public function up() { Schema::create('mcmraak_catalog_items', function($table) { $table->engine = 'InnoDB'; $table->increments('id'); $table->string('name'); $table->integer('category_id'); }); } public function down() { Schema::dropIfExists('mcmraak_catalog_items'); } } |
Таблица mcmraak_catalog_categorys будет содержать два столбца:
- id (integer)
- name (string)
Вот её миграция:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php namespace Mcmraak\Catalog\Updates; use Schema; use October\Rain\Database\Updates\Migration; class BuilderTableCreateMcmraakCatalogCategorys extends Migration { public function up() { Schema::create('mcmraak_catalog_categorys', function($table) { $table->engine = 'InnoDB'; $table->increments('id'); $table->string('name'); }); } public function down() { Schema::dropIfExists('mcmraak_catalog_categorys'); } } |
Теперь создадим модели для данных таблиц:
Модели Item и Category
Обратим внимание на то где создаются эти модели, а именно в каталоге /plugins/mcmraak/catalog/models автоматически создались файлы моделей Item.php и Category.php. Запомним это место, оно нам пригодится.
Создадим формы и списки для моделей
Для модели Category
Начнём с формы и списка для модели Category, форма будет содержать только одно поле ввода name, список будет выводить только один столбец name. Всё просто потому-что для примера.
Создастся файл: /plugins/mcmraak/catalog/models/category/fields.yaml
1 2 3 4 5 6 |
fields: name: label: 'Имя категории' span: auto oc.commentPosition: '' type: text |
Список:
Создастся файл: /plugins/mcmraak/catalog/models/category/columns.yaml
1 2 3 4 |
columns: name: label: 'Имя категории' type: text |
Для модели Item:
Поле «название» сделать так-же как и для модели Category, а вот дополнительное поле «Категория» типа Dropdown, где мы будем выбирать категорию товара, делается так:
Создастся файл: /plugins/mcmraak/catalog/models/item/fields.yaml
1 2 3 4 5 6 7 8 9 10 11 |
fields: name: label: Название span: auto oc.commentPosition: '' type: text category_id: label: Категория span: auto oc.commentPosition: '' type: dropdown |
Список для модели Item будет не совсем обычный, внимание на скриншот:
Создастся файл: /plugins/mcmraak/catalog/models/item/columns.yaml
1 2 3 4 5 6 7 8 9 |
columns: name: label: Название type: text category_id: label: Категория type: number relation: category valueFrom: name |
Мы указали что в списке товаров нужно показывать не значение category_id а соответствующую запись из другой модели. Что-бы это отношение (belongsTo = обратное один-к-одному) работало, нужно задать ему имя, и имя ему будет category. Затем мы указали что из другой модели нам нужны не все данные экземпляра, а только из столбца name. (Я не знаю как проще написать, тут нужно знать что такое модели и вообще ORM).
Что-бы это работало, мы добавим в модель Item (/plugins/mcmraak/catalog/models/Item.php) следующее:
1 2 3 |
public $belongsTo = [ 'category' => 'Mcmraak\Catalog\Models\Category' ]; |
Что-бы работал наш Dropdown мы так-же добавим в модель такой код:
1 2 3 4 |
public function getCategoryIdOptions($keyValue = null) { return Category::lists('name', 'id'); } |
За метод ::lists особая благодарность Кириллу Попкову из сообщества https://vk.com/octobercms я реально не знал про этот метод модели и велосепедировал по своему перебором foreach.
В результате должно получится:
/plugins/mcmraak/catalog/models/Item.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<?php namespace Mcmraak\Catalog\Models; use Model; /** * Model */ class Item extends Model { use \October\Rain\Database\Traits\Validation; /* * Validation */ public $rules = [ ]; /* * Disable timestamps by default. * Remove this line if timestamps are defined in the database table. */ public $timestamps = false; /** * @var string The database table used by the model. */ public $table = 'mcmraak_catalog_items'; public $belongsTo = [ 'category' => 'Mcmraak\Catalog\Models\Category' ]; public function getCategoryIdOptions($keyValue = null) { return Category::lists('name', 'id'); } } |
Далее делаем для наших моделей контроллеры и пункты меню, кто забыл как это делается прочитать тут.
В результате получаем примерно следующее:
Пока что на этом всё. В данной статье показано как в OctoberCMS делать связи. Подробнее о том какие связи бывают ещё и как их правильно использовать читать уже тут https://laravel.com/docs/5.3/eloquent-relationships: