태그 보관물: best-practice

best-practice

다 대다 관계를 만들기위한 Magento 2의 모범 사례는 무엇입니까? ‘Stockist Id’)

나는 핵심을 둘러 보았고 모델 사이의 많은 관계에서 몇 가지 예를 보았지만 이것에 대한 명확한 대답을 볼 수는 없습니다.

예를 들어, 새 모델을 작성하고 기존 제품 테이블과 다 대다 관계를 원한다고 가정하십시오.

그래서 우리는 새로운 Model-Stockist를 가지고 있으며, 하나는 Stockist 이름을 저장하고, 다른 하나는 제품과 많은 관계를 저장하기 위해 2 개의 테이블을 만듭니다.

설정 클래스의 잘린 버전 :

$table = $setup->getConnection()
        ->newTable($installer->getTable('stockist'))
        ->addColumn('stockist_id',
            \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
            null,
            ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
            'Stockist Id')
        ->addColumn('name',
            \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
            null,
            ['nullable' => false],
            'Stockist Name');

 $table = $installer->getConnection()
            ->newTable($installer->getTable('stockist_product'))
            ->addColumn(
                'entity_id',
                \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
                null,
                ['identity' => true, 'nullable' => false, 'primary' => true],
                'Entity ID'
            )
            ->addColumn(
                'stockist_id',
                \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
                null,
                ['unsigned' => true, 'nullable' => false, 'primary' => true, 'default' => '0'],
                'Stockist ID'
            )
            ->addColumn(
                'product_id',
                \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
                null,
                ['unsigned' => true, 'nullable' => false, 'primary' => true, 'default' => '0'],
                'Product ID'
            )
            ->addIndex(
                $installer->getIdxName('stockist_product', ['product_id']),
                ['product_id']
            )
            ->addIndex(
                $installer->getIdxName(
                    'stockist_product,
                    ['stockist_id', 'product_id'],
                    \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
                ),
                ['stockist_id', 'product_id'],
                ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE]
            )
            ->addForeignKey(
                $installer->getFkName('stockist_product', 'product_id', 'catalog_product_entity', 'entity_id'),
                'product_id',
                $installer->getTable('catalog_product_entity'),
                'entity_id',
                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
            )
            ->addForeignKey(
                $installer->getFkName('stockist_product', 'stockist_id', 'stockist', 'stockist_id'),
                'stockist_id',
                $installer->getTable('stockist'),
                'stockist_id',
                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
            )
            ->setComment('Stockist to Product Many to Many');

그런 다음 Stockist에 대한 표준 Model / ResourceModel / Collection을 작성합니다.

namespace OurModule\Stockist\Model;

use Magento\Framework\Model\AbstractModel;

class Stockist extends AbstractModel
{

    protected function _construct()
    {
        $this->_init('OurModule\Stockist\Model\ResourceModel\Stockist');
    }

}

namespace OurModule\Stockist\Model\ResourceModel;

use Magento\Framework\Model\ResourceModel\Db\AbstractDb;

class Stockist extends AbstractDb
{

    protected function _construct()
    {
        $this->_init('stockist', 'stockist_id');
    }

}

namespace OurModule\Stockist\Model\ResourceModel\Stockist;

use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;

class Collection extends AbstractCollection
{

    public function _construct()
    {
        $this->_init('OurModule\Stockist\Model\Stockist', 'OurModule\Stockist\Model\ResourceModel\Stockist');
    }

}

여기에서 우리는 다 대다 관계로 테이블을 처리하는 방법을 알게되었습니다. 지금까지 나는 이것의 선을 따라 무언가를 생각해 냈습니다.

StockistProduct를 나타내는 모델 작성

namespace OurModule\Stockist\Model;

use Magento\Framework\Model\AbstractModel;

class StockistProduct extends AbstractModel
{

protected function _construct()
{
    $this->_init('OurModule\Stockist\Model\ResourceModel\StockistProduct');
}

/**
 * @param array $productIds
 */
public function getStockists($productIds)
{
    return $this->_getResource()->getStockists($productIds);
}

/**
 * @param array $stockistIds
 */
public function getProducts($stockistIds)
{
    return $this->_getResource()->getProducts($stockistIds);
}
}

여기에서 재고 ID의 배열 중 하나를 가져 와서 일치하는 제품 ID의 배열을 반환하고 그 반대의 두 가지 방법을 정의합니다.

이것은 다 대 다 관계를 포함하는 stockist_product 테이블에 대한 자원 모델을 사용합니다.

/**
 * Class StockistProduct
 */
class StockistProduct extends AbstractDb
{
    /**
     * Model initialization
     *
     * @return void
     */
    protected function _construct()
    {
        $this->_init('stockist_product', 'entity_id');
    }

    /**
     * Retrieve product stockist Ids
     *
     * @param array $productIds
     * @return array
     */
    public function getStockists(array $productIds)
    {
        $select = $this->getConnection()->select()->from(
            $this->getMainTable(),
            ['product_id', 'stockist_id']
        )->where(
            'product_id IN (?)',
            $productIds
        );
        $rowset = $this->getConnection()->fetchAll($select);

        $result = [];
        foreach ($rowset as $row) {
            $result[$row['product_id']][] = $row['stockist_id'];
        }

        return $result;
    }


    /**
     * Retrieve stockist product Ids
     *
     * @param array $stockistIds
     * @return array
     */
    public function getProducts(array $stockistIds)
    {
        $select = $this->getConnection()->select()->from(
            $this->getMainTable(),
            ['product_id', 'stockist_id']
        )->where(
            'stockist_id IN (?)',
            $stockistIds
        );
        $rowset = $this->getConnection()->fetchAll($select);

        $result = [];
        foreach ($rowset as $row) {
            $result[$row['product_id']][] = $row['stockist_id'];
        }

        return $result;
    }
}

그런 다음 $ stock에 제품 모델이 있고 $ stockistProduct가 \ OurModule \ Stockist \ Model \ StockistProduct의 인스턴스라고 가정하면 두 모델 중 하나를 검색해야 할 때이 StockistProduct 모델을 사용하십시오.

$stockists = $stockistProduct->getStockists([$product->getId()]);

그런 다음 리턴 된 ID 목록을 반복하여 각 모델을 차례로 작성할 수 있습니다. 여기서 $ stockistFactory는 \ OurModule \ Stockist \ Model \ StockistFactory의 인스턴스입니다.

$stockist = $this->stockistFactory->create();
$stockist->load($stockistId);

이 모든 것이 잘 작동하고 Core of Magento 2 내의 유사한 코드를 기반으로하지만 더 나은 방법이 있는지 궁금해 할 수는 없습니까?



답변

이와 비슷한 솔루션을 구현했습니다. 각 SKU에 대해 “피트먼트”정보가있었습니다 : 제품 (자동차 액세서리)을 적용 할 수있는 자동차의 연도, 제조사, 모델. 그것의 얼굴에, 이것은 네이티브 마 젠토 속성으로 가장 쉽습니다. 1 년, 1 년, 1 년, 3 개의 텍스트 필드 만 사용하십시오. 이를 통해 이러한 속성을 사용한 검색 및 필터링과 같은 모든 내장 Magento 기능과 향후 업데이트가 용이합니다.

설명 하듯이 문제는 이러한 관계의 “많은”이 필요하다는 것입니다. year1, make1, model1, year2, make2, model2, … year10, make10, model10과 같은 30 개의 텍스트 속성을 만들 수 있습니다. 이것은 a) 빈 속성을 많이 남겨두고 b) 제품이 지원하는 자동차의 수를 인위적으로 제한합니다.

작동 할 수있는 것은 다음과 같습니다.

Year: ____
Make: ____
Model: ____

Add new YearMakeModel relationship (+)

그런 다음 더하기 (+)를 클릭하면 다음이 표시됩니다.

Year: ____
Make: ____
Model: ____

Year: ____
Make: ____
Model: ____

Add new YearMakeModel relationship (+)

이러한 UI는 지원 테마 템플릿 내에서 자바 스크립트로 구현할 수 있습니다. 양식을 제출하면이 데이터를 제품 속성으로 Magento에 제공해야합니다. 현재 동적 길이를 지원하는 속성 유형이 없다고 생각합니다. 사용자 정의 속성 유형을 구현할 것입니다. 다시 말하지만, 내장 된 Magento 기능을 지원합니다. 입력 된 속성 검색, 향후 이러한 속성을 쉽게 업데이트합니다.

결국 고객은이 “쉬운 편집”을 구현하지 않음으로써 비용을 절감하기로 결정했으며, 대신 설명대로 사용자 정의 테이블에 데이터를 잠급니다. CSV 입력 및 출력을 테이블로 가져 오는 사용자 지정 가져 오기 스크립트가 있습니다. 나중에 제품 페이지 (자체 블록)가이 테이블을 쿼리하고 SKU에 대한 정보를 가져 와서 사용자에게 테이블로 표시합니다. 이 제품 페이지 테이블은 클라이언트가 원하는 동작이므로 “Magento Way”를 수행하고 변수 멤버 속성을 구현하는 것은 의미가 없습니다.


답변