Ich habe mich im Kern umgesehen und einige Beispiele für viele bis viele Beziehungen zwischen Modellen gesehen, aber ich sehe keine endgültige Antwort darauf.
Nehmen wir zum Beispiel an, wir erstellen ein neues Modell und möchten eine viel zu viele Beziehung zur vorhandenen Produkttabelle haben.
Wir haben also unser neues Model - Stockist und erstellen zwei Tabellen, eine zum Speichern des Stockist - Namens, die andere zum Speichern der vielen zu vielen Beziehungen zu Produkten.
Verkürzte Version der Setup-Klassen:
$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');
Dann erstellen wir ein Standardmodell / ResourceModel / Collection für Stockist wie folgt:
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');
}
}
Hier kommen wir zum Umgang mit dem Tisch in der Beziehung von vielen zu vielen. Bisher habe ich mir etwas in dieser Richtung ausgedacht.
Erstellen Sie ein Modell zur Darstellung von 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);
}
}
Hier werden zwei Methoden definiert, die entweder eine Reihe von Händler-IDs aufnehmen und eine Reihe von übereinstimmenden Produkt-IDs zurückgeben und umgekehrt.
Dies verwendet ein Ressourcenmodell für die Tabelle stockist_product, die die Beziehung many to many enthält:
/**
* 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;
}
}
Verwenden Sie dieses StockistProduct-Modell dann, wenn Sie einen Satz beider Modelle abrufen müssen, vorausgesetzt, wir haben ein Produktmodell in $ product und $ stockistProduct ist eine Instanz von \ OurModule \ Stockist \ Model \ StockistProduct
$stockists = $stockistProduct->getStockists([$product->getId()]);
Wir können dann jedes Modell der Reihe nach erstellen, indem wir die Liste der zurückgegebenen IDs durchlaufen, wobei $ stockistFactory eine Instanz von \ OurModule \ Stockist \ Model \ StockistFactory ist
$stockist = $this->stockistFactory->create();
$stockist->load($stockistId);
Das alles funktioniert gut und basiert auf einem ähnlichen Code im Core von Magento 2, aber ich frage mich, ob es einen besseren Weg gibt.