У попередніх статтях ми продемонстрували, як створити нові таблиці у базі даних Magento 2. З цієї статті ви дізнаєтеся про моделі для роботи з даними бази даних, які дозволять читати, редагувати та видаляти дані.
Magento 2 і Magento 1 для цих цілей використовує Model/ResourceModel/Collection ORM (Object-relational mapping). Для реалізації такої концепції необхідно створити 3 файли (модель, ресурс модель, колекцію).
1. Створіть файл моделі (Model):
app/code/VendorName/ModuleName/Model/Somemodel.php
помістіть у нього код:
<?php
namespace VendorName\ModuleName\Model;
class Somemodel extends \Magento\Framework\Model\AbstractModel
{
protected function _construct()
{
$this->_init('VendorName\ModuleName\Model\ResourceModel\Somemodel');
}
}
У _construct ініціалізується ресурс модель. Передаєте назву класу ресурс моделі (її створите у наступному кроці) у метод _init.
Модель (Model) - те, з чим ви найчастіше працюватимете. Цей клас необхідно унаслідувати від \Magento\Framework\Model\AbstractModel або його нащадків. Він відповідає за роботу над одним записом у таблиці. Найбільш вживаними методами цього класу є:
Методи завантаження:
load($id) - завантажить запис, первинний ключ якого рівний $id;
load($value, $columnName) - завантажить запис, значення колонки $columnName якого рівне $value;
Методи отримання і задання значень ("Ґетери і сетери"):
getSomeKey() - отримає значення для властивості (колонки) some_key;
getData('some_key') - аналог getSomeKey;
setSomeKey($value) - задасть значення для властивості (колонки) some_key;
setData('some_key', $value) - аналог setSomeKey;
getId() - отримає значення первинного ключа;
setId($id) - задасть значення первинного ключа;
Метод збереження та видалення:
save() - збереже дані у базі даних. Якщо первинний ключ не заданий, створить новий запис;
delete() - видалить запис, ключ якого збігається із ключем об'єкту моделі;
Інші методи:
getCollection() - повертає об'єкт колекції;
getResource() - повертає об'єкту ресурс моделі;
З додатковими методами ви можете ознайомитися самостійно, дослідивши класи:
\Magento\Framework\Model\AbstractModel
\Magento\Framework\DataObject
2. Створіть файл ресурс моделі (Resource Model):
app/code/VendorName/ModuleName/Model/ResourceModel/Somemodel.php
помістіть у нього код:
<?php
namespace VendorName\ModuleName\Model\ResourceModel;
class Somemodel extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
protected function _construct()
{ $this->_init('table_name_without_prefix', 'primary_column_name'); }
}
table_name_without_prefix - назва таблиці у базі даних Magento 2, без префіксу;
primary_column_name - назва поля у цій таблиці з primary ключем та автоінкрементом.
Методи завантаження і збереження у моделі працюють з базою даних через ресурс модель.
3. Створіть файл колекції (Collection):
app/code/VendorName/ModuleName/Model/ResourceModel/Somemodel/Collection.php
помістіть у нього код:
<?php
namespace VendorName\ModuleName\Model\ResourceModel\Somemodel;
class Collection
extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
protected function _construct()
{ parent::_construct();
$this->_init(
'VendorName\ModuleName\Model\Somemodel',
'VendorName\ModuleName\Model\ResourceModel\Somemodel'
); }
}
У метод _init потрібно передавати назви класів моделі та ресурс моделі.
Колекція відповідає за завантаження декількох записів із таблиці. Найбільш вживаними методами цього класу є:
addFieldToFilter($field, $condition) - додає обмеження "WHERE $field = $condition";
addFieldToSelect($field) - вказує, які колонки включати у запит. По замовчуванні усі колонки включені у запит;
setOrder($field, $direction) - вказує сортування "ORDER BY $field $direction";
setPageSize($size) - вказує на обмеження "LIMIT $size";
setCurPage($page) - задає номер сторінки;
Ознайомтеся з іншими методами самостійно, дослідивши класи:
\Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
\Magento\Framework\Data\Collection\AbstractDb
\Magento\Framework\Data\Collection
Приклад роботи із колекцією:
$collection = $this->collectionFactory->create();
$collection->addFieldToFilter('status', 1)
->addFieldToFilter('publish_date', ['lteq' => '2017-11-01'])
->setPageSize(10);
foreach ($collection as $item) {
echo $item->getName();
}
Цей код виконує запит до бази даних і отримує перших 10 записів, у яких колонка status рівна 1 і publish_date менша або рівна 2017-11-01, після чого циклом виводить значення колонки 'name' для кожного отриманого запису.
У прикладах ми розробляємо модуль для поширених запитань FAQ. Змінений код модуля можна переглянути на GitHub.