Cách thực hành tốt nhất trong Magento 2 để tạo mối quan hệ Nhiều đến Nhiều là gì?


15

Tôi đã nhìn xung quanh lõi và thấy một vài ví dụ về nhiều mối quan hệ giữa nhiều người mẫu, nhưng tôi không thể thấy câu trả lời dứt khoát về điều này.

Ví dụ, giả sử chúng ta tạo một mô hình mới và chúng ta muốn có nhiều mối quan hệ với nhiều bảng sản phẩm hiện có.

Vì vậy, chúng tôi có Mô hình mới - Stockist và chúng tôi tạo 2 bảng như vậy, một bảng để lưu trữ tên Stockist, bàn còn lại để lưu trữ nhiều mối quan hệ với nhiều sản phẩm.

Phiên bản rút gọn của các lớp thiết lập:

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

Sau đó, chúng tôi tạo một Model / ResourceModel / Collection tiêu chuẩn cho Stockist như sau:

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

}

Đây là nơi chúng ta đến để làm thế nào để xử lý bảng với nhiều mối quan hệ nhiều. Cho đến nay tôi đã nghĩ ra một cái gì đó dọc theo dòng này.

Tạo một mô hình để đại diện cho Stockist sản phẩm

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

Ở đây xác định 2 phương thức sẽ lấy một mảng Id stockist, trả về một mảng Id sản phẩm phù hợp và ngược lại.

Điều này sử dụng Mô hình tài nguyên cho bảng stockist_product chứa nhiều mối quan hệ với nhiều:

/**
 * 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;
    }
}

Sau đó, sử dụng mô hình StockistSản phẩm này khi bạn cần truy xuất một bộ mô hình như vậy, giả sử chúng ta có Mô hình sản phẩm trong sản phẩm $ và $ stockistSản phẩm là một ví dụ của \ OurModule \ Stockist \ Model \ StockistS

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

Sau đó, chúng ta có thể tạo lần lượt từng mô hình bằng cách lặp danh sách Id được trả về, trong đó $ stockistFactory là một phiên bản của \ OurModule \ Stockist \ Model \ StockistFactory

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

Tất cả đều hoạt động tốt và dựa trên một số mã tương tự trong Core of Magento 2, nhưng tôi không thể tự hỏi liệu có cách nào tốt hơn không?


Tôi phải làm một cái gì đó rất giống nhau ... và đây là ý tưởng duy nhất tôi có, nếu không có câu trả lời :(
slayerbleast

Câu trả lời:


1

Tôi đã thực hiện một giải pháp tương tự như thế này. Đối với mỗi SKU, có thông tin "đồ đạc": năm, kiểu dáng, mẫu xe mà sản phẩm (phụ kiện xe hơi) có thể được áp dụng. Trên mặt của nó, điều này sẽ dễ dàng nhất với các thuộc tính Magento bản địa. Chỉ cần sử dụng ba trường văn bản, một cho năm, một cho thực hiện, một cho mô hình. Điều này cho phép tất cả các chức năng Magento tích hợp, như tìm kiếm và lọc với các thuộc tính này, cùng với việc cập nhật dễ dàng trong tương lai.

Vấn đề, như bạn mô tả, là chúng ta cần "nhiều" các mối quan hệ này. Chúng ta có thể tạo 30 thuộc tính văn bản: year1, make1, model1, year2, make2, model2, ... year10, make10, model10. Điều này sẽ a) có thể để lại nhiều thuộc tính trống và b) tạo giới hạn nhân tạo cho số lượng xe mà sản phẩm hỗ trợ.

Những gì có thể làm việc là một cái gì đó như thế này:

Year: ____
Make: ____
Model: ____

Add new YearMakeModel relationship (+)

Và sau khi nhấp vào dấu cộng (+), bạn sẽ thấy:

Year: ____
Make: ____
Model: ____

Year: ____
Make: ____
Model: ____

Add new YearMakeModel relationship (+)

Một giao diện người dùng như vậy có thể được triển khai với javascript bên trong một mẫu chủ đề được hỗ trợ. Khi gửi biểu mẫu, bạn sẽ cần cung cấp dữ liệu này cho Magento dưới dạng các thuộc tính sản phẩm. Tôi không nghĩ hiện tại có một loại thuộc tính hỗ trợ độ dài động. Bạn sẽ thực hiện một loại thuộc tính tùy chỉnh. Một lần nữa, điều này cung cấp hỗ trợ từ chức năng Magento tích hợp: tìm kiếm các thuộc tính đã nhập, cập nhật dễ dàng cho các thuộc tính này trong tương lai.

Cuối cùng, khách hàng của chúng tôi đã đưa ra quyết định tiết kiệm tiền bằng cách không thực hiện "chỉnh sửa dễ dàng" này và thay vào đó chúng tôi đã khóa dữ liệu trong một bảng tùy chỉnh, giống như bạn mô tả. Tôi có một tập lệnh nhập tùy chỉnh nhận đầu vào và đầu ra CSV vào bảng. Sau đó, trang sản phẩm (tốt, khối của nó) tạo các truy vấn cho bảng này, lấy ra thông tin về SKU của nó và hiển thị cho người dùng dưới dạng bảng. Bảng trang sản phẩm này là hành vi mong muốn từ khách hàng, vì vậy đối với chúng tôi, không có ý nghĩa gì khi thực hiện "Cách thức Magento" và thực hiện một thuộc tính thành viên biến.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.