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


15

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

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

그래서 우리는 새로운 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 내의 유사한 코드를 기반으로하지만 더 나은 방법이 있는지 궁금해 할 수는 없습니까?


나는 매우 비슷한 일을해야합니다 ... 그리고 대답이 없으면 이것이 내가 가진 유일한 아이디어입니다 :(
slayerbleast

답변:


1

이와 비슷한 솔루션을 구현했습니다. 각 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"를 수행하고 변수 멤버 속성을 구현하는 것은 의미가 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.