Nette Documentation Preview

syntax
Modelo
******

A medida que nuestra aplicación crece, pronto descubrimos que necesitamos realizar operaciones de base de datos similares en varias ubicaciones y en varios presentadores, por ejemplo, adquirir los artículos publicados más recientes. Si mejoramos nuestra aplicación añadiendo una bandera a los artículos para indicar un estado de trabajo en curso, también debemos recorrer todas las ubicaciones de nuestra aplicación y añadir una cláusula where para asegurarnos de que sólo se seleccionan los artículos terminados.

En este punto, el trabajo directo con la base de datos resulta insuficiente y será más inteligente ayudarnos con una nueva función que devuelva los artículos publicados. Y cuando añadamos otra cláusula más adelante (por ejemplo para no mostrar artículos con fecha futura), sólo editaremos nuestro código en un lugar.

Colocaremos la función en la clase `PostFacade` y la llamaremos `getPublicArticles()`.

Crearemos nuestra clase modelo `PostFacade` en el directorio `app/Model/` para que se encargue de nuestros artículos:

```php .{file:app/Model/PostFacade.php}
<?php
namespace App\Model;

use Nette;

final class PostFacade
{
	public function __construct(
		private Nette\Database\Explorer $database,
	) {
	}

	public function getPublicArticles()
	{
		return $this->database
			->table('posts')
			->where('created_at < ', new \DateTime)
			->order('created_at DESC');
	}
}
```

En la clase pasaremos la base de datos Explorer:[api:Nette\Database\Explorer]. Esto aprovechará la potencia del [contenedor DI |dependency-injection:passing-dependencies].

Pasaremos a `HomePresenter` que editaremos de forma que nos deshagamos de la dependencia de `Nette\Database\Explorer` sustituyéndola por una nueva dependencia de nuestra nueva clase.

```php .{file:app/UI/Home/HomePresenter.php}
<?php
namespace App\UI\Home;

use App\Model\PostFacade;
use Nette;

final class HomePresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private PostFacade $facade,
	) {
	}

	public function renderDefault(): void
	{
		$this->template->posts = $this->facade
			->getPublicArticles()
			->limit(5);
	}
}
```

En la sección de uso, estamos usando `App\Model\PostFacade`, por lo que podemos acortar el código PHP a `PostFacade`. Solicitamos este objeto en el constructor, lo escribimos en la propiedad `$facade` y lo usamos en el método renderDefault.

El último paso que queda es enseñar al contenedor DI a producir este objeto. Esto se hace normalmente añadiendo una viñeta al archivo `config/services.neon` en la sección `services`, dando el nombre completo de la clase y los parámetros del constructor.
Esto lo registra, por así decirlo, y el objeto se llama entonces **service**. Gracias a una magia llamada [autocableado |dependency-injection:autowiring], normalmente no necesitamos especificar los parámetros del constructor porque DI los reconocerá y los pasará automáticamente. Por lo tanto, bastaría con proporcionar el nombre de la clase:

```neon .{file:config/services.neon}
...

services:
	- App\Model\PostFacade
```

Sin embargo, tampoco es necesario añadir esta línea. En la sección `search` al principio de `services.neon` se define que todas las clases que terminen en `-Facade` o `-Factory` serán buscadas por DI automáticamente, lo que también es el caso para `PostFacade`.


Resumen .[#toc-summary]
=======================

La clase `PostFacade` pide `Nette\Database\Explorer` en un constructor y como esta clase está registrada en el contenedor DI, el contenedor crea esta instancia y la pasa. DI de esta manera nos crea una instancia de `PostFacade` y se la pasa en un constructor a la clase HomePresenter que la pidió. Una especie de muñeca Matryoshka de código :) Todos los componentes sólo piden lo que necesitan y no les importa dónde y cómo se crea. La creación es manejada por el contenedor DI.

.[note]
Aquí puedes leer más sobre [inyección de dependencias |dependency-injection:introduction], y sobre [configuración |nette:configuring].

{{priority: -1}}
{{sitename: Nette Quickstart}}

Modelo

A medida que nuestra aplicación crece, pronto descubrimos que necesitamos realizar operaciones de base de datos similares en varias ubicaciones y en varios presentadores, por ejemplo, adquirir los artículos publicados más recientes. Si mejoramos nuestra aplicación añadiendo una bandera a los artículos para indicar un estado de trabajo en curso, también debemos recorrer todas las ubicaciones de nuestra aplicación y añadir una cláusula where para asegurarnos de que sólo se seleccionan los artículos terminados.

En este punto, el trabajo directo con la base de datos resulta insuficiente y será más inteligente ayudarnos con una nueva función que devuelva los artículos publicados. Y cuando añadamos otra cláusula más adelante (por ejemplo para no mostrar artículos con fecha futura), sólo editaremos nuestro código en un lugar.

Colocaremos la función en la clase PostFacade y la llamaremos getPublicArticles().

Crearemos nuestra clase modelo PostFacade en el directorio app/Model/ para que se encargue de nuestros artículos:

<?php
namespace App\Model;

use Nette;

final class PostFacade
{
	public function __construct(
		private Nette\Database\Explorer $database,
	) {
	}

	public function getPublicArticles()
	{
		return $this->database
			->table('posts')
			->where('created_at < ', new \DateTime)
			->order('created_at DESC');
	}
}

En la clase pasaremos la base de datos Explorer. Esto aprovechará la potencia del contenedor DI.

Pasaremos a HomePresenter que editaremos de forma que nos deshagamos de la dependencia de Nette\Database\Explorer sustituyéndola por una nueva dependencia de nuestra nueva clase.

<?php
namespace App\UI\Home;

use App\Model\PostFacade;
use Nette;

final class HomePresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private PostFacade $facade,
	) {
	}

	public function renderDefault(): void
	{
		$this->template->posts = $this->facade
			->getPublicArticles()
			->limit(5);
	}
}

En la sección de uso, estamos usando App\Model\PostFacade, por lo que podemos acortar el código PHP a PostFacade. Solicitamos este objeto en el constructor, lo escribimos en la propiedad $facade y lo usamos en el método renderDefault.

El último paso que queda es enseñar al contenedor DI a producir este objeto. Esto se hace normalmente añadiendo una viñeta al archivo config/services.neon en la sección services, dando el nombre completo de la clase y los parámetros del constructor. Esto lo registra, por así decirlo, y el objeto se llama entonces service. Gracias a una magia llamada autocableado, normalmente no necesitamos especificar los parámetros del constructor porque DI los reconocerá y los pasará automáticamente. Por lo tanto, bastaría con proporcionar el nombre de la clase:

...

services:
	- App\Model\PostFacade

Sin embargo, tampoco es necesario añadir esta línea. En la sección search al principio de services.neon se define que todas las clases que terminen en -Facade o -Factory serán buscadas por DI automáticamente, lo que también es el caso para PostFacade.

Resumen

La clase PostFacade pide Nette\Database\Explorer en un constructor y como esta clase está registrada en el contenedor DI, el contenedor crea esta instancia y la pasa. DI de esta manera nos crea una instancia de PostFacade y se la pasa en un constructor a la clase HomePresenter que la pidió. Una especie de muñeca Matryoshka de código :) Todos los componentes sólo piden lo que necesitan y no les importa dónde y cómo se crea. La creación es manejada por el contenedor DI.

Aquí puedes leer más sobre inyección de dependencias, y sobre configuración.