I'm trying to build a custom module that contains an EAV entity in Magento 2 for learning purposes.
I have troubles performing a proper save from an admin controller.
I'm trying to avoid code like:

$data = get data from post here; 

Because the save method is deprecated and because I'm trying to work with interfaces instead of their implementations.

For a flat entity I could do this:

$entity = either get it from a repository or via factory;
$data = get data from post
$this->dataObjectHelper->populateWithArray($entity, $data, EntityInterface::class);

Where dataObjectHelper is an instance of \Magento\Framework\Api\DataObjectHelper that reads the setters of the interface passed as the 3rd parameter and maps the corresponding to the methods from the $data array to my entity.

So if $data looks like this:

$data = [
    'title'=>'Some title',
    'description' => 'Some description'

will just call $entity->setTitle('Some title')->setDescription('Some description').

But I cannot do that for the EAV entities because my entity interface will contain only the system attributes and not the custom ones.

I need to get the data from POST and pass it to the $entity instance and then call $entityRepository->save($entity) but I don't want to lose any custom attributes.

How can I proceed in this case?
I looked in the core and for products and categories the controllers still call $entity->save() which is not OK.


So, from what I understood, Magento 2 is slowly switching to the EntityManager which is used to extract and hydrate the entities.

Populating the data

To populate the data, you need to use the hydrator so \Magento\Framework\EntityManager\Hydrator :

$entity = $this->hydrator->hydrate($entity, $dataArray);

Saving the entity

That's already halfway implemented in 2.1. Let's look at the product resource model save() method:

public function save(\Magento\Framework\Model\AbstractModel $object)
    return $this;

That is the right way of doing it. The only thing not implemented yet is that it's still trigerred via the save() call because the deprecated method still calls $this->_getResource()->save($this);

| improve this answer | |

How about populating your data as usual, but using the resource to perform the save.

At least that's how I currently work around the deprecation issue.

| improve this answer | |
  • This is kind of how it works. But I want to use repositories (which call $resourceModel->save($entity)) but I'm trying to stick to interfaces. So my Repository save method accepts as parameter an instance of MyEntityInterface. – Marius Sep 27 '16 at 12:56

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.