Well, the first step you should check for the model in question is: Is there a Repository Service Contract? If so, use that, because Service Contracts are bound to semantic versioning and will continue to behave like they should up until Magento 3.x comes out. Needless to say, when you create your own modules with models that require persistence, you should also write the repository for that.
public function __construct(
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository
) {
$this->productRepository = $productAttributeRepository;$productRepository;
/** @var \Magento\Catalog\Api\Data\ProductInterface $product */
$this->productRepository->save($product);
}
If there is no repository present, use the resource model. Note that resource models don't contain a state: they're utilizing persistence for their 'regular' models. Therefore you are not required to include them using a factory:
public function __construct(
\Magento\Catalog\Model\ResourceModel\Product $productResource,
\Magento\Catalog\Model\ProductFactory $productFactory
) {
$this->productResource = $productResource;
$this->productFactory = $productFactory;
...
/** @var \Magento\Catalog\Api\Data\ProductInterface $product */
$product = $this->productFactory->create();
$this->productResource->save($product);
}
"So what benefit brings a Service Contract / Repository over a Resource Model?" you might ask. Well, in theory a Resource Model should only be responsible for the persistence of a Data Model, whereas a Repository also takes into account the additional tasks involved upon saving an entity. Think about updating indexes, creating relations with other entities, etc. This is the theory, although in real life these lines tend to blur quite often. But it's good for yourself to keep this in mind.
You should not use the models' direct save()
, load()
, etc. -methods. They are deprecated because it's semantic incorrect. Think about it in a SOLID way:
- (Data) Models should only be responsible for containing data.
- Resource Models should be responsible for the persistence of such data.
- Repositories should be responsible for the communication inside and outside the module for persistence actions.
And it's that last point that makes a difference: when communicating with other modules, in an ideal world one should never have to rely on that modules' internal persistent logic (or any of it's public methods for that matter, but that's another discussion), but only use that functionality that is provided by the modules' Service Contracts.
In Conclusion
To answer your question: in order of preference. The correct way to load a model is:
- If there is a Repository, load it using the Repository.
- Only if there is no Repository, use the Resource Model (in combination with a factory).