2

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.

2

2 Answers 2

2

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);

5
2

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.

1
  • 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
    Commented Sep 27, 2016 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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