Question

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; 
$myObj->addData($data)->save();

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.

Was it helpful?

Solution

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)
{
    $this->getEntityManager()->save($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);

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top