Diferencias entre Model, ResourceModel y Collection en Magento 2
Creamos las tablas y sus relaciones con el fichero db_schema.xml. Si la versión de Magento 2 es menor a 2.3, tendremos que usar InstallSchema.php o UpgradeSchema.php.
Si queremos sacar un conjunto de datos, tendremos que usar Collection. Si queremos sacar datos de forma individual usaremos el ResourceModel. El ResourceModel lo usaremos básicamente para hacer las operaciones CRUD (create, read, update y delete) de los datos de la base de datos. Pero la manera correcta es encapsularlo mediante el Model.
Usaremos el Factory Pattern para instanciar Model, ResourceModel y Collection. Importante, No se usa el patrón Singleton para los models. Tiene que ser instancias independientes. La instancia se creará en los ficheros generados dinámicamente en la carpeta generated. Si usas el IDE PHPSTORM, verás que se quejará de que el fichero o el método factory no existe. Eso es que porque se tiene que generar dinámicamente. Si estás en el entorno de desarrollo, tendrás que limpiar la carpeta generated , limpiar el caché y recargar la página. Si el entorno está en modo producción, tendrás que ejecutar el comando setup:di:compile para la generación de los ficheros dinámicos en generated. Sin embargo,en muchas ocasiones, veo que Magento usa interfaces en vez de factories. Estas interfaces son mapeadas en di.xml, quizás cada inyección de la interface en la clase es un objeto. Si queremos usar objetos independientes tenemos que usar factories.
Por ej:
// instanciar la clase model $model = $this->modelFactory->create(); // instanciar la clase ResourceModel $resourcemodel = $this->resourcemodelFactory->create() // sacar datos con resourcemodel . Ojo! si queremos que esto esté bien hecho, encapsularlo en la clase Repository. $entity_id = 2; $resourcemodel->load($model, $entity_id);
// se mapean interfaces y modelos // app/etc/di.xml
El Model contiene los datos en formato de DataObject. Entonces para editar un dato y guardarlo en la bbdd, se hace de la siguiente manera:
// Ojo podríamos encapsular el siguiente código en un fichero aparte, en el repository $model = $this->modelFactory->create(); $resourcemodel = $this->resourcemodelFactory->create() $entity_id = 2; $resourcemodel->load($model, $entity_id); // cambiar valor a las propiedes del DataObject $model->setData('nombre', 'David'); $model->setData('apellido', 'Carrillo'); // Guardar el objeto model con las propiedades cambiadas $resourcemodel->save($model);
Usaremos la Collection cuando queremos un listado de datos. Mediante la Collection, podemos ordenar los datos, filtrarlos, limitarlos para la paginación etc. Usaremos también el patrón Factory para la creación de la instancia.
Luego están los api y repository, es un patrón. Le llaman service contracts. En el repository classes instaciaremos el model y no crearemos instancia del resource. Pero cuando queramos usar un objeto de repository , sí instaciaremos la clase con el método create().
Pongo otro ejemplo muy usual en Magento 2 en la gestión de los datos.
// Buscar el id de un registro filtrando por unos valores de campo. $entityId = $this->collectionFactory->create() -> addFieldToSelect... ->addFieldToFilter ... ->getLastItem... ->getId... // rellenamos las propiedades del model, de valores traídos de la bbdd . Las propiedades estarán definidas en API/DATA. Pueden No estar definidas. $model = $this->model->create() $this->resource->load(model, entityId, opcional='entityid') // a partir de ahora ya podemos hacer lo que queramos $this->resource->save() $this->resource->delete.. etc // conviene hacer un check si el id de la fila existe o no . Si existe eliminar.