อะไรคือวิธีปฏิบัติที่ดีที่สุดใน Magento 2 สำหรับการสร้างความสัมพันธ์แบบหลายต่อหลายคน?


15

ฉันดูรอบแกนกลางและเห็นตัวอย่างของความสัมพันธ์แบบหลายต่อหลายถึงหลายแบบ แต่ฉันไม่เห็นคำตอบที่ชัดเจนเกี่ยวกับเรื่องนี้

ตัวอย่างเช่นสมมติว่าเราสร้างโมเดลใหม่และเราต้องการมีความสัมพันธ์แบบหลายต่อหลายกับตารางผลิตภัณฑ์ที่มีอยู่

ดังนั้นเราจึงมี Model - Stockist ใหม่ของเราและเราสร้าง 2 ตารางดังกล่าวหนึ่งรายการเพื่อเก็บชื่อ Stockist และอีกรายการหนึ่งเพื่อจัดเก็บความสัมพันธ์แบบหลายต่อหลายกับผลิตภัณฑ์

คลาสการตั้งค่าที่ถูกตัดทอน:

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

จากนั้นเราจะสร้าง Model / ResourceModel / Collection มาตรฐานสำหรับ Stockist ดังนี้:

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

ที่นี่กำหนด 2 วิธีที่จะใช้ในอาร์เรย์ของรหัส stockist ส่งกลับอาร์เรย์ของรหัสสินค้าที่ตรงกันและในทางกลับกัน

สิ่งนี้ใช้โมเดลทรัพยากรสำหรับตาราง 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;
    }
}

จากนั้นใช้รูปแบบ StockistProduct นี้เมื่อคุณต้องการดึงชุดของทั้งสองโมเดลดังนั้นสมมติว่าเรามีรูปแบบผลิตภัณฑ์ใน $ product และ $ stockistProduct เป็นตัวอย่างของ \ OurModule \ StockistProduct \ Modelisto StockistProduct

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

จากนั้นเราสามารถสร้างแต่ละแบบจำลองโดยการวนลูปรายการ Ids ที่ส่งคืนเช่นนั้นโดยที่ $ stockistFactory เป็นตัวอย่างของ \ OurModule \ Stockist \ Model \ StockistFactory

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

ทั้งหมดนี้ใช้งานได้ดีและใช้รหัสที่คล้ายกันใน Core of Magento 2 แต่ฉันอดไม่ได้ที่จะสงสัยว่ามีวิธีที่ดีกว่านี้หรือไม่


ฉันต้องทำสิ่งที่คล้ายกันมาก ... และนี่เป็นความคิดเดียวที่ฉันมีถ้าไม่มีคำตอบ :(
slayerbleast

คำตอบ:


1

ฉันใช้โซลูชันที่คล้ายกับสิ่งนี้ สำหรับแต่ละ SKU มีข้อมูล "การประกอบ": ปียี่ห้อรุ่นของรถยนต์ที่สามารถใช้ผลิตภัณฑ์ (อุปกรณ์เสริมในรถยนต์) บนหน้าของมันนี้จะง่ายที่สุดด้วยคุณสมบัติ Magento ดั้งเดิม เพียงใช้ฟิลด์ข้อความสามฟิลด์หนึ่งครั้งต่อปีหนึ่งฟิลด์สำหรับทำหนึ่งฟิลด์สำหรับโมเดล สิ่งนี้ทำให้ฟังก์ชั่น Magento ในตัวทั้งหมดเช่นการค้นหาและการกรองด้วยคุณสมบัติเหล่านี้พร้อมกับการอัพเดทที่ง่ายดายในอนาคต

ปัญหาดังที่คุณอธิบายคือเราต้องการความสัมพันธ์เหล่านี้ "มาก" เราสามารถสร้าง 30 คุณสมบัติข้อความ: ปี 1, make1, model1, ปี 2, make2, model2, ... ปี 10, make10, model10 a) มีแนวโน้มที่จะปล่อยแอตทริบิวต์ที่ว่างเปล่าไว้มากมายและ b) สร้างข้อ จำกัด ด้านเทียมกับจำนวนรถยนต์ที่ผลิตภัณฑ์รองรับ

สิ่งที่สามารถใช้งานได้มีดังนี้:

Year: ____
Make: ____
Model: ____

Add new YearMakeModel relationship (+)

จากนั้นหลังจากคลิกเครื่องหมายบวก (+) คุณจะเห็น:

Year: ____
Make: ____
Model: ____

Year: ____
Make: ____
Model: ____

Add new YearMakeModel relationship (+)

UI ดังกล่าวสามารถนำไปใช้กับ javascript ภายในเทมเพลตธีมที่มีการสำรอง เมื่อส่งแบบฟอร์มคุณจะต้องให้ข้อมูลนี้แก่ Magento เป็นคุณสมบัติของผลิตภัณฑ์ ฉันไม่คิดว่าขณะนี้มีประเภทแอตทริบิวต์ที่รองรับความยาวแบบไดนามิก คุณจะใช้ประเภทแอตทริบิวต์ที่กำหนดเอง อีกครั้งนี้ให้การสนับสนุนจากฟังก์ชั่น Magento ในตัว: การค้นหาคุณสมบัติที่ป้อนการอัพเดทง่าย ๆ สำหรับแอตทริบิวต์เหล่านี้ในอนาคต

ในท้ายที่สุดลูกค้าของเราได้ตัดสินใจที่จะประหยัดเงินโดยไม่ใช้ "การแก้ไขอย่างง่าย" และเราจะทำการเก็บข้อมูลไว้ในตารางที่กำหนดเองเช่นเดียวกับที่คุณอธิบาย ฉันมีสคริปต์นำเข้าแบบกำหนดเองที่ใช้อินพุตและเอาต์พุต CSV ลงในตาราง หลังจากนั้นหน้าผลิตภัณฑ์ (ก็บล็อก) ทำแบบสอบถามไปยังตารางนี้ดึงข้อมูลเกี่ยวกับ SKU ของมันและแสดงให้ผู้ใช้เป็นตาราง ตารางหน้าผลิตภัณฑ์นี้เป็นพฤติกรรมที่ต้องการจากลูกค้าดังนั้นสำหรับเราแล้วมันไม่สมเหตุสมผลเลยที่จะขุดลงในการทำ "The Magento Way" และใช้แอททริบิวต์ตัวแปรสมาชิก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.