5

If I understand correctly, Magento 2 moves more and more to the strict use of data models instead of creating models that are tied-in with their resource models and have all kind of business logic that, well... just are not within the responsibility of those models.

You can see this shift by looking at the naming used for the service contracts: Api/Data/xxxInterface are interfaces for data models. If you look at the customer module you can see the related data models in Model/Data/*. These are models that extend from AbstractExtensibleObject, which in it turn extends Magento\Framework\Api\AbstractSimpleObject.

Please, if anything if the above is mis-assumption or incorrect, please tell me what the proper Magento 2 philosophy is.

Now ...

I'm trying to create a module that uses solely data models and UI Components to generate the list and the form etc. This works fine, but as soon as I have to be able to create a collection, I have to provide a model that extends from Magento\Framework\DataObject. This is set in the _init() method of Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection:

/**
 * Define resource model
 */
protected function _construct()
{
    $this->_init(
        'Vendor\Module\Model\Data\Foo',
        'Vendor\Module\Model\ResourceModel\Foo'
    );
}

Now, if I do this, I get the exception:

Vendor\Module\Model\Data\Foo does not extend \Magento\Framework\DataObject

Which makes sense, because data models extend from Magento\Framework\Api\AbstractSimpleObject.

Now I don't want to create a dummy model just for this, that doesn't seem right, so I peeked how this is handled in the framework itself in Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult. This is a class that is used as a virtualType in di.xml and provides a collection for the listing. And like I said, that worked. So how did they pull this off?

Well it looked like they did:

$this->_init($this->document, $resourceModel);

And $this->document is the name of \Magento\Framework\View\Element\UiComponent\DataProvider\Document, which in it's turn extends \Magento\Framework\DataObject.

So with this knowledge, I edited my own collection like this:

/**
 * Define resource model
 */
protected function _construct()
{
    $this->_init(
        \Magento\Framework\View\Element\UiComponent\DataProvider\Document::class,
        'Happy\PrivateDownloads\Model\ResourceModel\Download'
    );
}

And now it works.

But, just because it works doesn't necessarily mean that this is the correct solution. So that's why I'm asking this question in the community:

Is this the proper way to create collections from data models?

Any answer / help / insights would be greatly appreciated!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.