10 Jan, 2021

Magento 2 Resource Models, A better way to save.

If you develop in Magento 2 you likely noticed that the save() functionality on most core Models is now deprecated.

If you look at the deprecated notice you’ll see that it says:

100.1.0 because entities must not be responsible for their own persistence. Service contracts should persist in entities. Use resource model “save” to implement service contract persistence operations.

Said differently, saving directly to the object is now discouraged – while this is true and the benefits of doing so should not be discounted, that’s not the point of this article.

In typical Magento fashion, they choose to tell you there is a new best practice without explaining the beneficial “why”. This leads to a lot of developers feeling like it’s yet another arbitrary change Magento chose to make on a bugfix release. They’ll either end up using the new way because they don’t want to be judged or just to pass code reviews, not for their understood benefit.

The real benefit of saving using a resource model can be simplified using a single word, speed.

Typically when using a Model, you’ll load the Model, make your changes, then save the entire Model.

$data = "string";
$product = $this-productRepo->get($productId);
$product->setData('attribute_code', $data);
$product->save();

As you can see above it’s a very straight-forward idea that’s easy to understand and implement.

The same functionality still exists with a Resource Model but the implementation is slightly different.

$data = "string";
$product = $this-productRepo->get($productId);
$product->setData('attribute_code', $data);
$this->productResourceModel->save($product);

Both implementations achieve the same goal of loading a product and saving a product. This is where it becomes hard to see the difference between the deprecated function and the new “best practice” making the change feel arbitrary.

Let’s get to the exciting part, the benefit of using a Resource Model. I’m going to use Magento\Catalog\Model\ResourceModel\Product class to explain the actual benefit of Resource Models.

The product Resource Model has a function called saveAttribute(). This function requires passing the product Model and the attribute.

Here’s how to use it:

$data = "string";
$product = $this-productRepo->get($productId);
$product->setData('attribute_code', $data);
$this->productResourceModel->saveAttribute($product, 'attribute_code');

Again, very similar to the previous examples when using the Model and Resource Model save functions.

The difference is this, when saving we’re not saving the entire object, we’re only saving the specific attribute. Normally when saving an object each attribute is loaded then the data is saved, regardless of if new data is being saved or if it’s the same data that existed – whether you save a single attribute or multiple attributes, all attributes are being saved. Now, we’re only loading and saving the attribute specified in the second parameter of the saveAttribute() function.

Using this new functionality you’re able to save exponential amounts of time when compared to the standard save() function. I often work product catalogs in the thousands and commonly see this saving minutes of time when mass updating products.

This new and improved functionality allows for faster data manipulation paving the way for more product changes, improved cron job performance, and fewer time-outs when updating large catalogs.

Hopefully this article helps you in your Magento development journey. Be sure to check back for more articles & content like this.

You may also like...