phpmagento2magento-2.3

Overriding Magento_SalesRule ResourceModel by preferences throws error: Type Error occurred when creating object


Error Message in debug.log:

[2020-11-10 07:57:17] main.CRITICAL: Type Error occurred when creating object: Magento\SalesRule\Model\ResourceModel\Rule, Argument 3 passed to Magento\SalesRule\Model\ResourceModel\Rule::__construct() must be an instance of Magento\SalesRule\Model\ResourceModel\Coupon, instance of RM\SameCouponMultipleDiscounts\Model\ResourceModel\Coupon given, called in /home/rehan/lab/testrm/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 116 [] []

I am trying to override: Magento\SalesRule\Model\ResourceModel\Coupon.php to remove 'unique coupon' restriction:

$this->addUniqueField(['field' => 'code', 'title' => __('Coupon with the same code')]);

from construct() method.

My app/code/Vendor/Module/Model/ResourceModel/Coupon.php looks like:

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Vendor\Module\Model\ResourceModel;

use Magento\Framework\Model\AbstractModel;

/**
 * SalesRule Resource Coupon
 *
 * @author      Magento Core Team <core@magentocommerce.com>
 */
class Coupon extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb implements
    \Magento\SalesRule\Model\Spi\CouponResourceInterface
{
    /**
     * Constructor adds unique fields
     *
     * @return void
     */
    protected function _construct()
    {
        $this->_init('salesrule_coupon', 'coupon_id');
    }
}

my di.xml file looks like:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\SalesRule\Model\ResourceModel\Coupon" type="Vendor\Module\Model\ResourceModel\Coupon" />
</config>

I've tried clearing cache, generated folder and did setup:di:compile but I am still receiving the same error.


Solution

  • You should make your overridden class extends the original class so the other native classes that dependency injection original class can recognize your overridden one.

    Alter

    class Coupon extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb implements
        \Magento\SalesRule\Model\Spi\CouponResourceInterface
    

    into

    class Coupon extends \Magento\SalesRule\Model\ResourceModel\Coupon
    

    But using preferences aren't recommended, you can try to find a better way.