3/22/2018 - #development #ecommerce #magento
by: Kévin Weyhaupt

Intro

If the new year’s good resolutions seem far away and are almost forgotten, we want to help you to set up at least one of them : realise a good data model for your future projects on Magento 2. Therefore I have put together a quick recipe, eventhough this is not proper French cuisine I hope this will satisfy your hunger. As a recipe, there will be different steps to realise and here is the list of ingredients and preparation to make :



In this article I will use these two entity : “Student” and “Teacher” in order to have an associative table (student has many teachers and vice versa). First and foremost I need to clarify two things. First of all, the code examples don’t have a PHP Doc for space savings reasons, but it is, of course, a good practice that good developers should do. (You will find the full commented code here : https://github.com/blackbird-agency/magento-2-data-model-sample).Secondly, this article only concerns “classic” data models (i.e. with different entities and relations between them) but not EAV ; Entity Attribute Value.
schéma tables

Part 1: Preparing the main ingredients

A large chunk of Service Contract...

Firstly, what is the “Service Contract”? Well, the “Service Contract” is the contract between the developer and the code of the application. In other words, it is a set of interfaces that will help us to define the services and structures of the different data models. For our recipe we will use some of them but we won’t be able to see them all. (It will probably be the topic of a future article).

Defining our models

First of all, the interfaces of the “Service Contract” are defined in a folder named “Api” placed in the root folder of the module concerned. In this folder, we will create another one called “Data” where we will put our interfaces referring to each of the models with the accessors and the static properties such as the names of the fields in the base so that they can be easily modified, with no needs to browse our code entirely. Here the tag @api of the PHPDoc shows that the class is actually included in the api and that we can trust it.

<?php
namespace MyVendor\MyModule\Api\Data;
/**
* Student Interface
* @api
*/
interface StudentInterface
{
  const ID = 'student_id';
  const NAME = 'name';
  public function getId();
  public function getName();
  public function setId($id);
  public function setName($name);
}


Realising the model

Once the interfaces of the service contracts are ready, we are now able to implement them in MyVendor\MyModule\Model.

Implementation of the models

The aim here is simply to implement the accessors by using the class properties defined in the interface. Our model will inherit from Abstract Model for different reasons :

  • Using the method “_init” in the constructor in order to link it with the “resource model” and thus make the relation between our object and the data base. (I’ll explain the “resource model” in the second part).
  • Managing the attributes of our objects with, for instance :
    • setData/getData: allows to define or to get the value of an attribute.
    • setOrigData/getOrigData: allows to get the datas of our object when instancing, i.e. the initial values coming from the data base.
    • --This way Magento will only update the datas that have been modified.
  • Using the magic methods, i.e. the methods beginning with set, get, uns or also has + the name of the attribute (in camelCase) to manage an attribute, if the object itself doesn’t have any methods to access it yet.

In cases where our object is rather simple and is just here to manipulate some datas (and potentially manage the update in the base, using services) it is more interesting to inherit from AbstractSimpleObject because it is lighter  when it only offers the methods get/setData et __toArray. If on top of simple object we also want to use the collections without necessarily inheriting from the AbstractModel, then we can use the DataObject.

<?php
namespace MyVendor\MyModule\Model;
use Magento\Framework\Model\AbstractModel;
use MyVendor\MyModule\Api\Data\StudentInterface;
class Student extends AbstractModel implements StudentInterface
{
protected function _construct()
{
    parent::construct();
$this->_init(\MyVendor\MyModule\Model\ResourceModel\Student::class)
;
}
  public function getId()
  {
    return $this->_getData(self::ID);
  }
 
  public function getName()
  {
    return $this->_getData(self::NAME);
  }

  public function setId($id)
  {
    return $this->setData(self::ID, $id);
  }

  public function setName($name)
  {
    return $this->setData(self::NAME, $name);
  }
}

Adjust the seasoning with “dependency injection”

Injection of dependency is used in different framework. It helps to determine the dependencies between the modules and handles the instantiation and the injection of the passed parameters.
Magento 2 works this way, the point here is to draw a correlation between our interfaces of the service contract and the “preference” tag. This will enable to tell that every time we call our interface "Student" of the API, the concrete class of the model will be used. Therefore, in order to respect the good practices, if you want to use the model you will have to use the API's interface. 

This good practive makes it easier to maintain the code and also improve its flexibility.

<?xml version="1.0"?> 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
  <preference for="MyVendor\MyModule\Api\Data\StudentInterface" 
type="MyVendor\MyModule\Model\Student"/>
  <preference for="MyVendor\MyModule\Api\StudentRepositoryInterface" 
type="MyVendor\MyModule\Model\StudentRepository"/>
</config>

Clearly, injection of dependency is not all about this little piece of code. The more you will follow this recipe, the more you'll learn about it !  

First part is now over. A recipe often requires to let the preparation for rest a little while, so go and grab a coffee and come back for the second part : adding flavour. Because it’s nice to have some objects, but honestly speaking, don’t you think they are a little bit too bland?


>>> Read the second part : Adding Flavour.

Write your comment

Ready
for take-off?

Blackbird is a web agency specialized in the development of eCommerce websites. We are Magento Experts and we offer our services and advice for e-marketing, strategy, branding, deployment and methodology.

Contact
+339 50 66 21 38


Legal terms
Agency 30, Avenue du Rhin
67100 Strasbourg
France
SEE MAP
FR - EN