Veamos primero qué sucede si usa el save()
método directamente en un product
modelo como
/**
* @var Magento\Catalog\Model\Product $product
*/
$product->save();
La clase de modelo en sí es
Magento\Catalog\Model\Product
Dentro de esta clase, busque la definición del método save ().
Ninguno encontrado ¿verdad? Bueno, hay beforeSave () y afterSave (), pero no save () en sí. Interesante, no?
Luego, debemos mirar las clases principales de Magento\Catalog\Model\Product
.
Necesitamos pasar Magento\Catalog\Model\AbstractModel
y Magento\Framework\Model\AbstractExtensibleModel
, finalmente, llegar a Magento\Framework\Model\AbstractModel
.
Efectivamente, hay un método save () aquí y se ve algo así como
public function save()
{
$this->_getResource()->save($this);
return $this;
}
Vemos ahora, cada vez que se llama a save () en cualquier modelo, se llama al método save () AbstractModel
, y la implementación es que el MODELO DE RECURSOS realmente guarda.
Esto último no es sorprendente dado que siempre lo estamos, ya que desde el principio del tiempo en Magento 1.0, creamos un modelo y un modelo de recursos para casi cualquier entidad.
Ahora, echemos un vistazo a cómo ProductRepository
funciona.
Permite abrir archivo
/vendor/magento/module-catalog/Api/ProductRepositoryInterface.php
Esta interfaz exige que haya un método save (), entre otros métodos.
¿Quién está implementando realmente esta interfaz?
Permite abrir archivo
/etc/di.xml
y verifique la línea 10
<preference for="Magento\Catalog\Api\ProductRepositoryInterface" type="Magento\Catalog\Model\ProductRepository" />
Entonces, naturalmente, encontramos la implementación del método save () dentro
/vendor/magento/module-catalog/Model/ProductRepository
y comienza en la línea 444, luciendo como
public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveOptions = false)
{
$tierPrices = $product->getData('tier_price');
try {
.... other code here ....
Este método espera que se \Magento\Catalog\Api\Data\ProductInterface
pase un objeto $ product de tipo , pero por defecto esto se resuelve en Magento\Catalog\Model\Product
.
Mirando abajo en la línea 500, ganando una try
declaración, vemos algo así como
$this->resourceModel->save($product);
¡Lo has adivinado bien! $this->resourceModel
es de tipo \Magento\Catalog\Model\ResourceModel\Product
, declarado como protected
propiedad en la línea 77.
Entonces, de nuevo, en ResourceModel
realidad hace el ahorro.
Pero, entre la línea 444 y 500 es en realidad la respuesta a su pregunta. Todo el código ejecutado aquí, de hecho, eventualmente puede y conducirá a diferencias de comportamiento entre el guardado directo del modelo y esta forma de guardar el repositorio.
Por ejemplo, el repositorio de productos obtendrá y procesará enlaces de productos si ignore_links_flag
está configurado como 0
, compruebe si este es un producto existente en primer lugar, etc.
Probablemente necesitemos concluir que si es necesario cambiar la forma en que se guarda el producto en el futuro, quizás la mejor manera de hacerlo es anular el repositorio del producto en lugar del modelo del producto.
Lo mismo vale para guardar y actualizar productos. Prefiero usar el objeto del repositorio del producto.
También me remito amablemente a /vendor/magento/module-cms/Model/PageRepository.php
Así es como se guardaría una página CMS a través del repositorio. Aquí, las cosas son más simples. Se establece la identificación de la tienda y se llama al modelo de recurso para guardar de inmediato.
Con este último aviso, concluirá que en algunos casos, puede que no haya tantas diferencias entre el repositorio y el guardado del modelo, pero de todos modos espero que esté equipado para detectarlos cada vez que necesite hacerlo.