Хорошая практика: как сохранить много объектов?


У меня есть вопрос относительно хорошей практики: как правильно сохранить много объектов?

Предположим, я изменил множество объектов в коллекции, скажем, в коллекции продуктов. Вот что я мог бы сделать:

...

foreach($productCollection as $product{
    $this->productRepository->save($product);
}

...

Однако использование метода сохранить() в цикле не только плохая практика, но и подчеркивается PHP CS. Конечно, если коллекция содержит только 4 или 5 продуктов, это не изменит облик мира, но иногда это явно наиболее чем это.

Я знаю, что если я изменяю только атрибут, мне не нужно использовать репозиторий и я могу использовать встроенный компонент Magento для обновления атрибутов, однако иногда мне также нужно выполнить некоторую логику и действительно нужна сущность продукта.

Итак, у кого-нибудь есть хорошая практика, которой можно поделиться в этом контексте?

Author: enrico69, 2017-03-11

1 answers

Если вам нужно выполнить массовое обновление одного (или нескольких атрибутов) до одного и того же значения, вы можете использовать:

$this->_objectManager->get('Magento\Catalog\Model\Product\Action')
    ->updateAttributes($productIds, ['status' => $status], $storeId);

В этом примере мы обновляем все продукты, соответствующие идентификатору ($productIds - это массив идентификаторов продуктов), устанавливая их статус атрибут к значению $status, для магазина $ Хранитель.

Если вы хотите просто обновить один атрибут в коллекции продуктов, вы можете использовать (в своем случай):

...
foreach($productCollection as $product{
    $product->addAttributeUpdate($attributeCode, $value, $store);
}
...

$ Код атрибута представляет имя атрибута, которое должно быть сохранено

$ ценность представляет значение, которое вы хотите установить для сущности

$ хранить представляет идентификатор магазина, это может быть $product->getstoreid()

Проблема с Добавить атрибут обновить() является ли это атрибутом обновления, но он не обновляет загруженную в данный момент модель продукта. Взгляните на реализацию в Magento\Catalog\Model\Product:

/**
 * Save current attribute with code $code and assign a new value
 *
 * @param string $code  Attribute code
 * @param mixed  $value New attribute value
 * @param int    $store Store ID
 * @return void
 */
public function addAttributeUpdate($code, $value, $store)
{
    $oldValue = $this->getData($code);
    $oldStore = $this->getStoreId();

    $this->setData($code, $value);
    $this->setStoreId($store);
    $this->getResource()->saveAttribute($this, $code);

    $this->setData($code, $oldValue);
    $this->setStoreId($oldStore);
}

В этом случае лучше использовать что-то вроде, productResource является Magento\Catalog\Model\ResourceModel\Product :

...
foreach($productCollection as $product{
    // its sugessted to inject resource as dependency than using deprecated getResource() method. 
    // check reference for more information.
    // $product->getResource()->saveAttribute($product, $attributeCode);
       $this->productResource->saveAttribute($product, $attributeCode);
}
...

Недостаток этого решения становится заметным, когда вы работаете над большие коллекции. Вот почему у нас есть итераторы который захватывает данные из базы данных, один за другим, и таким образом предотвращает истощение памяти.

...
$this->_dataObject = $this->_objectManager->get('Magento\Catalog\Model\Product');

$iterator = $this->_objectManager->get('Magento\Framework\Model\ResourceModel\Iterator')

$iterator->walk($productCollection->getSelect(), [[$this, 'walkCallback']]);
...

public function walkCallback($data)
{
    $this->_dataObject->reset(); // clean up shared object
    $this->_dataObject->setData($data['row']); // map data to product model
    $this->_dataObject->setDescription('test');
    $this->_dataObject->getResource()->saveAttribute($this->_dataObject, 'description'); // save only changed attribute instead of whole object
}

Это идеи, которые вы можете использовать для управления коллекциями.

Ссылка: https://github.com/magento/magento-coding-standard/pull/189

 10
Author: Sinisa Nedeljkovic, 2020-08-29 16:06:38