5

I'm trying to update a field in the database via my database model. All tutorials online about CRUD models seem to just show how to 'CR' and not showing examples of the 'UD'. My code so far:

namespace CompanyName\AdminMenu\Controller\Adminhtml\HomepageBanner;

class UpdatePosition extends \Magento\Framework\App\Action\Action
{
protected $_postFactory;
protected $_httpRequest;
protected $_postResource;

public function __construct(
    \Magento\Framework\App\Action\Context $context,
    \Magento\Framework\App\Request\Http $httpRequest,
    \CompanyName\AdminMenu\Model\PostFactory $postFactory,
    \CompanyName\AdminMenu\ResourceModel\Post $postResource
    )
{
    $this->_postFactory = $postFactory;
    $this->_postResource = $postResource;
    $this->_httpRequest = $httpRequest;
    return parent::__construct($context);
}

public function execute()
{
    $post = $this->$postFactory->create();

    $post->load(2, 'slide_position')->setId(22)->save();

    //$this->getConnection()->update('admincontentbanners_homepageslider_post', ['slide_position' => $data], ["slide_id = ?" => $slideID]);
}

}

Any advise would be appreciated..

2
  • Use repository instead of model and cms module is good example of CRUD.
    – Sohel Rana
    Commented Jun 3, 2018 at 18:38
  • I didn't know about repositories.. Ill look into using those now.. Man, Magneto moves fast!
    – Bossman
    Commented Jun 3, 2018 at 19:06

2 Answers 2

5

This loads the specified model , which you want update .

public function execute()
    {
        $post = $this->$postFactory->create();
        $id_post_update = 19; //Example

        $postUpdate = $post->load($id_post_update);
        $postUpdate->setSlidePosition(2);
        $postUpdate->setId(22);
        $postUpdate->save();
    }
5
  • I'm going to look into repositories now but is "$id_post_update" the primary table ID field? "setSlidePosition()" is that a generated function?
    – Bossman
    Commented Jun 3, 2018 at 19:08
  • $id_post_update - this id entity post, which you want update ;"setSlidePosition()" - this magic method , which update 'slide_position' Commented Jun 3, 2018 at 19:17
  • Thanks for your help, i managed to get it working with your code, i didn't need the "$postUpdate->setId(22);"
    – Bossman
    Commented Jun 4, 2018 at 20:02
  • Sorry , I get this "->setId(22)" from your example . Commented Jun 4, 2018 at 20:13
  • Yes, that was just me not understanding fully :)
    – Bossman
    Commented Jun 4, 2018 at 21:17
4

Evgeniy Kapelko approach works, but deprecated from Magento 2.1(with certain version I might be mistaken).
Below infromation from class, that was used in Evgeniy Kapelko approach, confirm info about deprecation vendor/magento/framework/Model/AbstractModel.php

/**
 * Save object data
 *
 * @return $this
 * @throws \Exception
 *
 * @deprecated 100.1.0 because entities must not be responsible for their own persistence.
 * Service contracts should persist entities. Use resource model "save" to implement
 * service contract persistence operations.
 */
public function save()
{
    $this->_getResource()->save($this);
    return $this;
}


How correct to work with you model?
We need to use it like described in official documentation.

It can be little bit hard at the begging, but future code will be simple and clear.

In code below, we are going to update Shop entity name.
1) Create interface for you repository, with functions getById and save

<?php

namespace Vendor\Module\Api;

use Vendor\Module\Api\Data\ShopInterface;

/**
 * Interface SampleInterface
 *
 * @package Academy\Database\Api\Data
 */
interface ShopRepositoryInterface
{

    /**
     * @param \Vendor\Module\Api\Data\ShopInterface $shopList
     *
     * @return mixed
     */
    public function save(ShopInterface $shopList);

    /**
     * @param int $id
     *
     * @return mixed
     */
    public function getById(int $id);
}

2) Implement interface in you repository and define functions

<?php

namespace Vendor\Module\Model;


use Vendor\Module\Api\Data\ShopInterface;
use Vendor\Module\Api\ShopRepositoryInterface;
use Vendor\Module\Model\ResourceModel\Shop as ShopResource;
use Magento\Framework\Exception\AlreadyExistsException;

class ShopRepository implements ShopRepositoryInterface
{

    /**
     * @var ShopFactory
     */
    private $shopList;
    /**
     * @var Shop
     */
    private $shopListResource;

    public function __construct(
        ShopFactory $shopList,
        ShopResource $shopListResource
    ) {
        $this->shopList         = $shopList;
        $this->shopListResource = $shopListResource;
    }

    /**
     * @param ShopInterface $shop
     *
     * @return void
     *
     * @throws AlreadyExistsException
     * @throws \Exception
     */
    public function save(ShopInterface $shop)
    {
        try {
            $this->shopListResource->save($shop);
        } catch (AlreadyExistsException $e) {
            //catch exception
        } catch (\Exception $e) {
            //catch exception
        }
    }

    /**
     * @param int $shopId
     *
     * @return \Vendor\Module\Model\Shop
     */
    public function getById(int $shopId)
    {
        $shopListModel = $this->shopList->create();
        $this->shopListResource->load($shopListModel, $shopId);

        return $shopListModel;
    }
}

3) Add Repository and RepositoryInterface to di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Vendor\Module\Api\ShopRepositoryInterface"
                type="Vendor\Module\Model\ShopRepository"/>
</config>

4) Start using it (i'm using it in controller)

    /**
     * @param ShopInterfaceFactory    $shopListFactory
     * @param ShopRepositoryInterface $shopListRepository
     */
    public function __construct(
        \Vendor\Module\Api\Data\ShopInterfaceFactory $shopListFactory,
        \Vendor\Module\Api\ShopRepositoryInterface $shopListRepository
    ) {
        $this->shopListFactory    = $shopListFactory;
        $this->shopListRepository = $shopListRepository;
    }

    public function execute()
    {
        $shopId = 1;//use needed entity ID

        /**
         * Create entity
         *
         * @var Shop $shopList
         */
        $shopList = $this->shopListFactory->create();
        $shopList->setData(['name' => 'shop name']);
        $this->shopListRepository->save($shopList);

        /**
         * Read entity
         *
         * @var Shop $shopList
         */
        $shopList = $this->shopListRepository->getById($shopId);
        $shopData = $shopList->getData();//data of entity

        /**
         * Update entity
         *
         * @var Shop $shopList
         */
        $shopList = $this->shopListRepository->getById($shopId);
        $shopList->addData(['name' => 'bdn']);
        $this->shopListRepository->save($shopList);
    }
5
  • This is correct but a strange use of naming from Magento side. setData creates and addData updates. It should be the other way around.
    – puntable
    Commented Dec 5, 2023 at 19:19
  • You can use setData and addData it's almost the same. github.com/pepe1518/magento2/blob/… github.com/pepe1518/magento2/blob/…
    – bakalov
    Commented Dec 7, 2023 at 8:02
  • If you have entity already and use $entity->setData(['some' => 'data']) it will create new object if you dont add identifier like this $entity->setData(['id' => 123, 'some' => 'data']). But $entity->addData(['some' => 'data']) will update correctly.
    – puntable
    Commented Dec 7, 2023 at 12:21
  • I can partly agree. I think the most important thing is: addData() - Add data to the object. setData() - Overwrite data in the object. And for setData is important it is an array or not. So in the case of setData('name', 'YourName') it will set this to the object this name and leave previous data in it. In the case of setData(['name' => 'YourName']) it will rewrite the values of this object. So we see by the doc, addData just calls setData one by one, that means it's not reset the whole object values.
    – bakalov
    Commented Dec 17, 2023 at 16:15
  • So, $shopList = $this->shopListRepository->getById($shopId); $shopList->addData(['name' => 'bdn']); $this->shopListRepository->save($shopList); is equal to $shopList = $this->shopListRepository->getById($shopId); $shopList->setData('name', 'bdn'); $this->shopListRepository->save($shopList);
    – bakalov
    Commented Dec 17, 2023 at 16:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.