Magento – Magento 2 : Insert Records in Multiple Table

databasemagento2resource-model

I have created 2 table :

table_1 :

  • id (Primary key)
  • name
  • status

table_2 :

  • sub_id (Primary key)

  • id (Foreign key table_1 id)

  • description

How to save records in both table using single model file?

Best Answer

I got this answer from this blog

https://lorenzosfarra.com/2017/05/19/magento2-database-transactions-how-to-save-multiple-model-instances/

But it makes sense. Something like this:

public function __construct(
    [..]
    \Some\Thing\Model\TableFactory $tableFactory,
    \Some\OtherThing\Model\TableFactory $table2Factory,
    \Magento\Framework\DB\TransactionFactory $transactionFactory
) {
    [..]
    $this->tableFactory = $tableFactory;
    $this->table2Factory = $table2Factory;
    $this->transactionFactory = $transactionFactory;
}
$transaction = $this->transactionFactory->create();

$tableInstance = $this->tableFactory->create();
$tableInstance->setField1($field1);
$transaction->addObject($tableInstance);
$tableInstance2 = $this->table2Factory->create();
$tableInstance2->setField2($field2);
$transaction->addObject($tableInstance2);

$transaction->save(); // single transaction

Another reference

Magento 2 - Database transaction for multiple model / resource model objects?

I can't think of a cleaner way to do it.

Update

CMS module uses extension pool concept. This is really difficult to follow and explain.

https://github.com/magento/magento2/blob/2.3-develop/app/code/Magento/Cms/etc/di.xml#L149-L176

    <type name="Magento\Framework\EntityManager\Operation\ExtensionPool">
        <arguments>
            <argument name="extensionActions" xsi:type="array">
                <item name="Magento\Cms\Api\Data\PageInterface" xsi:type="array">
                    <item name="read" xsi:type="array">
                        <item name="storeReader" xsi:type="string">Magento\Cms\Model\ResourceModel\Page\Relation\Store\ReadHandler</item>
                    </item>
                    <item name="create" xsi:type="array">
                        <item name="storeCreator" xsi:type="string">Magento\Cms\Model\ResourceModel\Page\Relation\Store\SaveHandler</item>
                    </item>
                    <item name="update" xsi:type="array">
                        <item name="storeUpdater" xsi:type="string">Magento\Cms\Model\ResourceModel\Page\Relation\Store\SaveHandler</item>
                    </item>
                </item>
                <item name="Magento\Cms\Api\Data\BlockInterface" xsi:type="array">
                    <item name="read" xsi:type="array">
                        <item name="storeReader" xsi:type="string">Magento\Cms\Model\ResourceModel\Block\Relation\Store\ReadHandler</item>
                    </item>
                    <item name="create" xsi:type="array">
                        <item name="storeCreator" xsi:type="string">Magento\Cms\Model\ResourceModel\Block\Relation\Store\SaveHandler</item>
                    </item>
                    <item name="update" xsi:type="array">
                        <item name="storeUpdater" xsi:type="string">Magento\Cms\Model\ResourceModel\Block\Relation\Store\SaveHandler</item>
                    </item>
                </item>
            </argument>
        </arguments>
    </type>

https://github.com/magento/magento2/blob/a74a8a82386589f9ed4d803d57edea874db8a822/app/code/Magento/Cms/Model/ResourceModel/Page/Relation/Store/SaveHandler.php#L46-L83

    public function execute($entity, $arguments = [])
    {
        $entityMetadata = $this->metadataPool->getMetadata(PageInterface::class);
        $linkField = $entityMetadata->getLinkField();

        $connection = $entityMetadata->getEntityConnection();

        $oldStores = $this->resourcePage->lookupStoreIds((int)$entity->getId());
        $newStores = (array)$entity->getStores();
        if (empty($newStores)) {
            $newStores = (array)$entity->getStoreId();
        }

        $table = $this->resourcePage->getTable('cms_page_store');

        $delete = array_diff($oldStores, $newStores);
        if ($delete) {
            $where = [
                $linkField . ' = ?' => (int)$entity->getData($linkField),
                'store_id IN (?)' => $delete,
            ];
            $connection->delete($table, $where);
        }

        $insert = array_diff($newStores, $oldStores);
        if ($insert) {
            $data = [];
            foreach ($insert as $storeId) {
                $data[] = [
                    $linkField => (int)$entity->getData($linkField),
                    'store_id' => (int)$storeId
                ];
            }
            $connection->insertMultiple($table, $data);
        }

        return $entity;
    }

Essentially PageInterface is linked to cms_page_store table

This might help

Magento 2 : extensionpool, read handlers and save handlers

Related Topic