Let us first see, what happens if you use the
save() method directly on a
product model like
* @var Magento\Catalog\Model\Product $product
The model class itself is
Within this class, search for the definition of the save() method.
None found right? Well, there's beforeSave() and afterSave(), but not save() itself. Interesting, no?
Then, we need to look at the parent classes of
We need to pass through
Magento\Framework\Model\AbstractExtensibleModel, just to finally arrive at
Sure enough, there is a save() method here and it looks something like
public function save()
We see now, whenever save() is called on any model, the save() method from this
AbstractModel is called, and the implementation is that the RESOURCE MODEL actually does the saving.
This last one is not surprising given that we are always, since like from the beggining of time in Magento 1.0, creating both a Model and a Resource model for just about any entity.
Now, lets take a look at how the
Lets open file
This interface demands that there is a save() method, among other methods.
Who is actually implementing this interface?
Lets open file
and check line 10
<preference for="Magento\Catalog\Api\ProductRepositoryInterface" type="Magento\Catalog\Model\ProductRepository" />
So, naturally we find the implentation of the save() menthod inside
and it starts on line 444, looking something like
public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveOptions = false)
$tierPrices = $product->getData('tier_price');
.... other code here ....
This method expects a $product object of type
\Magento\Catalog\Api\Data\ProductInterface passed, but by default this resolves to
Looking down below on line 500, winthin a
try statement, we see something like
You guessed well!
$this->resourceModel is of type
\Magento\Catalog\Model\ResourceModel\Product, declared as
protected property on line 77.
So, again, the
ResourceModel actually does the saving.
But, between line 444 and 500 is actually the answer to your question.
All the code executed here, indeed, eventually may and will lead to differences in behaviour between direct model save and this repository way of saving.
For example the product repository will get and process product links if the
ignore_links_flag is set to
0, check if this is an existing product in the first place etc.
We probably need to conclude that if any need in the future to change how the product is saved, perhaps the better way to do it is by overriding the product repository instead of the product model.
The same goes for saving and updating products. I'd rather use the product repository object.
I also kindly refer to you to /vendor/magento/module-cms/Model/PageRepository.php
This is how a CMS page would be saved via repository. Here, things are simpler. The store id is set and the resource model is called to save right away.
With this last notice, you will conclude that in some cases, there may not be that much differences between repository and model save, but anyway I hope you are equipped now to spot them whenever you need to do so.