Question

Magento 2.3.1 Php7.2 Ubuntu 18.04

I have created a table in my database using db_schema.xml and then populated that table with sql insert commands directly in mysql workbench.

My model code is

<?php

namespace Lmap\StarTrackShipping\Model\Carrier;

use Magento\Framework\Model\AbstractModel;



class StarTrackRates extends AbstractModel
{
    protected $_eventPrefix = 'startrack_rates_event';

    protected function _construct()
    {

        $this->_init(\Lmap\StarTrackShipping\Model\ResourceModel\StarTrackRates::class);

    }
}

ReosurceModel codes is

<?php
namespace Lmap\StarTrackShipping\Model\ResourceModel\Carrier;

use Magento\Framework\Model\ResourceModel\Db\AbstractDb;

class StarTrackRates extends AbstractDb
{
    protected function _construct()
    {
        $this->_init('lmap_shipping_tablerate', 'id');
    }

}

The collection Class is

<?php

namespace Lmap\StartrackShipping\Model\ResourceModel\Carrier\StarTrackRates;

use Lmap\StarTrackShipping\Model\Carrier\StarTrackRates;
use Lmap\StarTrackShipping\Model\ResourceModel\Carrier\StarTrackRates as StarTrackRatesResource;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;

/**
 * Start Track Shipping table rates collection
 */
class Collection extends AbstractCollection
{

    protected $_idFieldName = 'id';

    protected function _construct()
    {
        $this->_init(StarTrackRates ::class, StarTrackRatesResource::class);

    }

}

My Helper Method to retrieve row from the table

<?php

namespace Lmap\StarTrackShipping\Helper;

use Lmap\StarTrackShipping\Model\ResourceModel\Carrier\StarTrackRates\CollectionFactory;
use Lmap\StarTrackShipping\Model\Carrier\StarTrackRatesFactory;
use Lmap\StarTrackShipping\Model\Carrier\StarTrackRates;
use Psr\Log\LoggerInterface;

Class FetchShippingRate
{

    private $stRatesCollectionFactory;
    private $stRatesFactory;
    private $stRates;


    /**
     * @var \Psr\Log\LoggerInterface
     */
    private $logger;

    /**
     * @param \Psr\Log\LoggerInterface $logger
     * This construct with double underscore is required to initialize other classes as LoggerInterface, CollectionFactory etc
     * This concept is taken from Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate.php;
     */
    public function __construct(LoggerInterface $logger,CollectionFactory $CollectionFactory,StarTrackRatesFactory $StarTrackRatesFactory,StarTrackRates $StarTrackRates)
    {
        $this->logger = $logger;
        $this->stRatesCollectionFactory = $CollectionFactory;
        $this->stRatesFactory = $StarTrackRatesFactory;
        $this->stRates = $StarTrackRates;

    }

    public function fetchRate()
    {
        $var =2600;
        $postcode_rate_row = $this->stRatesCollectionFactory->create()->getItemsByColumnValue('postcode', 2600);
        $collection = $this->stRatesFactory->create()->getCollection();
        $collection->addFieldToSelect('*')->addFieldToFilter('postcode',array('eq'=>2600));

        foreach ($collection as $rate){
            $this->logger->debug('Rate is:');
            $this->logger->debug(var_dump($collection));
            $this->logger->debug(var_dump($rate->toarray(),'$rate'));
        }


        $this->logger->debug('Rates are: '.var_dump($postcode_rate_row));
        return $postcode_rate_row;

    }

Invoking fetchRate() method gives an empty array. I have used both approaches of using collectionFactory and using modelFactory method getCollection() but to no avail and I get empty array.

Looking at the folder tree there are two models Shipping and StarTrackRates. Shipping Model extends AbstractCarrier model hence I cannot connect it with my custom table via its own Shipping ResourceModel as one model can extend only one abstract model. Hence StarTrackRates model is created which extends abstract model along with its RsourceModel which extends AbstractDb to connect with custom table 'lmap_shipping_tablerate'.

When checkout is clicked then shipping model works and its collectRates(RateRequest $request) method invokes fetchRate() method defined in helper class FetchShippingRate using StarTrackRates Collection methods.

Here is the screen shot of the row I'm trying to retrieve. enter image description here

Furthermore, to test whether database table is accessed by any other way I have created Console/Commands as given in below folder structure.

enter image description here

I have created an add console command and delete console command and I add postcode with all other columns as follows

bin/magento lmap:postcode:add 2601 "NC3" 9.0816 0.4832 11.4127

This successfully added a row in the table 'lmap_shipping_tablerate' and deleted as follows

bin/magento lmap:postcode:add 2601 

The delete console command also implements the same collectionFactory as implemented in above helper method 'fetchRate()' and is successfully able to reach the table, get the desired postcode and delete the entire row as expected. Whereas helper method is not able to do the same.

Below is the section of the delete console command that does the job. Note getItemsByColumnValue collection method is working fine in delete console command but not in fetchRate() method of helper code.

protected function execute(InputInterface $input, OutputInterface $output)
{
    $itemName = $input->getArgument(self::INPUT_KEY_POSTCODE);
    $itemCollection = $this->collectionFactory->create()->getItemsByColumnValue('postcode',$itemName);
Was it helpful?

Solution 2

Instead of using CollectionFactory of (Model,ResourceModel,Collection) approach use getRate() method inside ResourceModel ResourceModelFile.php as follows along with some other default models. Hence ResourceModel ResourceModelFile.php is modified as follows.

    <?php
namespace MyVendor\MyModule\Model\ResourceModel;

use Magento\Framework\Model\ResourceModel\Db\AbstractDb;

class ResourceModelFile extends AbstractDb
{

    protected $logger;

    /**
     * 
     * @param \Magento\Framework\Model\ResourceModel\Db\Context $context
     * @param \Psr\Log\LoggerInterface $logger
     * @param null $connectionName
     */
    public function __construct(
        \Magento\Framework\Model\ResourceModel\Db\Context $context,
        \Psr\Log\LoggerInterface $logger,
        $connectionName = null
    ){
        parent::__construct($context, $connectionName);
        $this->logger = $logger;
    }

    /**
     * Connecting with Database table
     * This is special construct method with single underscore
     */
    protected function _construct()
    {
        $this->_init('your_table_name', 'id');
    }


    /**
     * @param \Magento\Quote\Model\Quote\Address\RateRequest $request
     * @return array
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getRate(\Magento\Quote\Model\Quote\Address\RateRequest $request)
    {
        $postcode = $request->getDestPostcode();

        $connection = $this->getConnection();
        $sql = $connection->select()->from($this->getMainTable())->where('postcode =?',$postcode);
        $result = $connection->fetchAll($sql);
        $this->logger->debug('The select with condition is:');
        $this->logger->debug(var_export($result,true));

        return $result;
    }

}

OTHER TIPS

Try Below code,

public function fetchRate()
{
    $var =2600;
    $postcode_rate_row = $this->stRatesCollectionFactory->create()->getItemsByColumnValue('postcode', 2600);
    $collection = $this->stRatesFactory->create()->getCollection();
    $collection->addFieldToSelect('*')->addFieldToFilter('postcode',array('eq'=>2600));

    $this->logger->debug('Rate Collection:' . var_dump($collection->getData());

    foreach ($collection as $rate){
        $this->logger->debug('Rate is:');
        $this->logger->debug(var_dump($rate->getData()));        
    }

    $this->logger->debug('Rates are: '.var_dump($postcode_rate_row->getData()));
    return $postcode_rate_row;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top