대량 작업에서 루프로 저장 피하기


13

CMS 페이지 와 비슷한 인라인 편집 작업을 포함하는 자체 CRUD 모듈을 만들었습니다.
모든 것이 정상적으로 작동하지만 EcgM2 표준으로 phpsniffer를 실행할 때 다음 경고가 표시됩니다.

루프에서 모델 LSD 메소드 save ()가 발견되었습니다.

어떻게 피할 수 있습니까?
참고 : 위에 링크 된 코어 파일을 "감지"하면 동일한 경고가 나타납니다. 누군가가 필요로하는 경우를 대비하여
execute방법이 있습니다. 하지만 CMS 페이지 컨트롤러와 매우 유사합니다.

public function execute()
{
    /** @var \Magento\Framework\Controller\Result\Json $resultJson */
    $resultJson = $this->jsonFactory->create();
    $error = false;
    $messages = [];

    $postItems = $this->getRequest()->getParam('items', []);
    if (!($this->getRequest()->getParam('isAjax') && count($postItems))) {
        return $resultJson->setData([
            'messages' => [__('Please correct the data sent.')],
            'error' => true,
        ]);
    }

    foreach (array_keys($postItems) as $authorId) {
        /** @var \Sample\News\Model\Author $author */
        $author = $this->authorRepository->getById((int)$authorId);
        try {
            $authorData = $this->filterData($postItems[$authorId]);
            $this->dataObjectHelper->populateWithArray($author, $authorData , AuthorInterface::class);
            $this->authorRepository->save($author);
        } catch (LocalizedException $e) {
            $messages[] = $this->getErrorWithAuthorId($author, $e->getMessage());
            $error = true;
        } catch (\RuntimeException $e) {
            $messages[] = $this->getErrorWithAuthorId($author, $e->getMessage());
            $error = true;
        } catch (\Exception $e) {
            $messages[] = $this->getErrorWithAuthorId(
                $author,
                __('Something went wrong while saving the author.')
            );
            $error = true;
        }
    }

    return $resultJson->setData([
        'messages' => $messages,
        'error' => $error
    ]);
}

답변:


5

이 경우 save()엔터티에 대한 것이므로 반드시 해당 메소드를 호출해야합니다.

링크 한 기본 핵심 Magento 파일이이를 수행하는 유일한 파일은 아니며 특히 대량 작업 동작 클래스입니다.

유일한 대안은 다음에서 saveAttribute구현 된 모델을 기반으로 CRUD 자원 모델에 메소드 를 추가하는 것입니다 app/code/Magento/Sales/Model/ResourceModel/Attribute.php.

public function saveAttribute(AbstractModel $object, $attribute)
{
    if ($attribute instanceof AbstractAttribute) {
        $attributes = $attribute->getAttributeCode();
    } elseif (is_string($attribute)) {
        $attributes = [$attribute];
    } else {
        $attributes = $attribute;
    }
    if (is_array($attributes) && !empty($attributes)) {
        $this->getConnection()->beginTransaction();
        $data = array_intersect_key($object->getData(), array_flip($attributes));
        try {
            $this->_beforeSaveAttribute($object, $attributes);
            if ($object->getId() && !empty($data)) {
                $this->getConnection()->update(
                    $object->getResource()->getMainTable(),
                    $data,
                    [$object->getResource()->getIdFieldName() . '= ?' => (int)$object->getId()]
                );
                $object->addData($data);
            }
            $this->_afterSaveAttribute($object, $attributes);
            $this->getConnection()->commit();
        } catch (\Exception $e) {
            $this->getConnection()->rollBack();
            throw $e;
        }
    }
    return $this;
}

이런 식으로 다음을 호출하는 대신

$this->authorRepository->save($author);

다음과 같은 작업을 수행 할 수 있어야합니다.

$author->getResource()->saveAttribute($author, array_keys($authorData));

의견에서 언급했듯이 필요 AbstractAttribute에 맞게 인스턴스를 확인할 필요가 없으면 해당 메소드를 약간 수정해야 합니다.


솔기가 합리적입니다. 감사. 나는 그것을 주사하고 결과와 함께 돌아올 것이다.
Marius

@Marius 그냥이 방법은 EAV의보다 약간 다르다는 것을 명심 saveAttribute대신 단지 하나의 속성 코드로 저장 "속성 코드"의 배열을 받아 같은 방법
디지털 Pianism에서 라파엘

1
나는 그것을 알아 차렸다. AbstractAttribute플랫 엔티티에 필요하지 않기 때문에 매개 변수로 허용하지 않고 인스턴스를 허용하지 않도록 조금 수정했습니다 . 원활하게 작동합니다. 다시 감사합니다.
Marius
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.