Magento 2'de Çoktan Çoka İlişkiler oluşturmak için en iyi uygulama yolu nedir?


15

Çekirdeğin etrafına baktım ve modeller arasındaki birçok ilişkiden birkaçına birkaç örnek gördüm, ancak bu konuda kesin bir cevap göremiyorum.

Örnek olarak, yeni bir model oluşturduğumuzu ve mevcut ürünler tablosuyla çoktan çoğa ilişkimiz olmasını istediğimizi düşünelim.

Bu yüzden yeni Modelimiz - Stockist'imiz var ve biri Stockist adını saklamak için diğeri ürünlerle çok fazla ilişkiyi saklamak için 2 tablo oluşturuyoruz.

Kurulum sınıflarının kesilmiş sürümü:

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

Sonra Stockist için standart bir Model / ResourceModel / Koleksiyon oluşturuyoruz:

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

}

Burası, çoktan çoğa ilişki ile masayı nasıl ele alacağımızdır. Şimdiye kadar bunun çizgileri boyunca bir şey buldum.

StockistProduct'ü temsil etmek için bir model oluşturun

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

Burada, eşleşen Ürün Kimlikleri dizisini döndüren ya da tam tersi bir stokçu kimliği dizisini alacak 2 yöntem tanımlanır.

Bu, stockist_product tablosu için çoktan çoğa ilişki içeren bir Kaynak Modeli kullanır:

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

Daha sonra bu StockistProduct modelini kullanarak her iki modelden birini almanız gerektiğinde, $ ürününde bir Ürün Modelimiz olduğunu ve $ stockistProduct \ OurModule \ Stockist \ Model \ StockistProduct örneğini varsayarsak

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

Daha sonra, her modeli sırayla döndürülen Ids listesini döngüye sokarak oluşturabiliriz, burada $ stockistFactory \ OurModule \ Stockist \ Model \ StockistFactory örneğidir

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

Tüm bunlar iyi çalışıyor ve Magento 2'nin Çekirdeği'nde bazı benzer kodlara dayanıyor, ancak daha iyi bir yol olup olmadığını merak edemiyorum?


Çok benzer bir şey yapmalıyım ... ve cevaplar yoksa, bu tek fikrim var :(
slayerbleast

Yanıtlar:


1

Buna benzer bir çözüm uyguladım. Her SKU için "teçhizat" bilgisi vardı: ürünün (otomobil aksesuarı) uygulanabileceği bir otomobilin yılı, markası, modeli. Yüzünde, bu yerel Magento nitelikleri ile en kolay olurdu. Biri yıl, biri marka, biri model için olmak üzere üç metin alanı kullanın. Bu, ileride kolay güncelleme ile birlikte bu özniteliklerle arama ve filtreleme gibi tüm yerleşik Magento işlevlerine izin verir.

Sorun, tarif ettiğiniz gibi, bu ilişkilerin "çoğuna" ihtiyacımız var. 30 metin özelliği yapabiliriz: yıl1, marka1, model1, yıl2, marka2, model2, ... yıl10, marka10, model10. Bu, a) muhtemelen birçok boş özellik bırakacak ve b) bir ürünün desteklediği araba sayısında yapay bir sınır oluşturacaktır.

Ne işe yarayabilir şuna benzer:

Year: ____
Make: ____
Model: ____

Add new YearMakeModel relationship (+)

Ve sonra artı (+) düğmesini tıkladıktan sonra şunu görürsünüz:

Year: ____
Make: ____
Model: ____

Year: ____
Make: ____
Model: ____

Add new YearMakeModel relationship (+)

Böyle bir kullanıcı arayüzü, desteklenen bir tema şablonunun içinde javascript ile uygulanabilir. Formu gönderdikten sonra, bu verileri Magento'ya ürün özellikleri olarak sağlamanız gerekir. Şu anda dinamik bir uzunluğu destekleyen bir özellik türü olduğunu sanmıyorum. Özel bir özellik türü uyguluyorsunuz. Yine, bu, yerleşik Magento işlevinden destek sağlar: girilen nitelikleri arama, gelecekte bu özellikler için kolay güncelleme.

Sonunda, müvekkilimiz bu "kolay düzenleme" yi uygulayarak paradan tasarruf etme kararı aldı ve bunun yerine, verileri açıkladığınız gibi özel bir tabloya kilitledik. CSV giriş ve çıkışları tabloya alır bir özel alma komut dosyası var. Daha sonra, ürün sayfası (bloğu) bu tabloya sorgu yapar, SKU'su hakkındaki bilgileri çıkarır ve kullanıcıya tablo olarak görüntüler. Bu ürün sayfası tablosu istemciden istenen davranıştı, bu yüzden bizim için "Magento Yolu" yapmak ve değişken üye niteliğini uygulamak mantıklı değildi.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.