Nette Documentation Preview

syntax
Modelo
******

À medida que nossa aplicação cresce, logo descobrimos que precisamos realizar operações similares de banco de dados em vários locais e em vários apresentadores, por exemplo, adquirindo os mais novos artigos publicados. Se melhorarmos nossa aplicação adicionando uma bandeira aos artigos para indicar um estado de trabalho em andamento, devemos também passar por todos os locais em nossa aplicação e adicionar uma cláusula de localização para garantir que apenas os artigos acabados sejam selecionados.

Neste ponto, o trabalho direto com o banco de dados torna-se insuficiente e será mais inteligente nos ajudar com uma nova função que retorna artigos publicados. E quando adicionamos outra cláusula posteriormente (por exemplo, para não exibir artigos com uma data futura), editamos nosso código apenas em um lugar.

Colocaremos a função na classe `PostFacade` e a chamaremos de `getPublicArticles()`.

Vamos criar nossa classe modelo `PostFacade` no diretório `app/Model/` para cuidar de nossos artigos:

```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');
	}
}
```

Na classe passamos no Explorer do banco de dados:[api:Nette\Database\Explorer]. Isto irá tirar proveito do poder do [recipiente DI |dependency-injection:passing-dependencies].

Mudaremos para `HomePresenter` que editaremos para nos livrarmos da dependência em `Nette\Database\Explorer`, substituindo-a por uma nova dependência de nossa nova classe.

```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);
	}
}
```

Na seção de uso, estamos usando `App\Model\PostFacade`, assim podemos encurtar o código PHP para `PostFacade`. Solicitamos este objeto no construtor, escrevemo-lo na propriedade `$facade` e o usamos no método renderDefault.

O último passo restante é ensinar o recipiente DI a produzir este objeto. Isto geralmente é feito adicionando um ponto no arquivo `config/services.neon` na seção `services`, dando o nome completo da classe e os parâmetros do construtor.
Isto o registra, por assim dizer, e o objeto é então chamado de **service***. Graças a alguma mágica chamada [autowiring |dependency-injection:autowiring], normalmente não precisamos especificar os parâmetros do construtor porque DI os reconhecerá e os passará automaticamente. Assim, seria suficiente apenas fornecer o nome da classe:

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

services:
	- App\Model\PostFacade
```

Entretanto, você também não precisa acrescentar esta linha. Na seção `search` no início de `services.neon` está definido que todas as classes que terminem com `-Facade` ou `-Factory` serão pesquisadas automaticamente por DI, o que também é o caso de `PostFacade`.


Sumário .[#toc-summary]
=======================

A classe `PostFacade` pede `Nette\Database\Explorer` em um construtor e como esta classe está registrada no container DI, o container cria esta instância e a passa. DI desta forma cria uma instância `PostFacade` para nós e a passa em uma construtora para a classe HomePresenter que a solicitou. Uma espécie de boneca Matryoshka de código :) Todos os componentes só pedem o que precisam e não se importam onde e como ele é criado. A criação é feita por um recipiente DI.

.[note]
Aqui você pode ler mais sobre [injeção de dependência |dependency-injection:introduction], e sobre [configuração |nette:configuring].

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

Modelo

À medida que nossa aplicação cresce, logo descobrimos que precisamos realizar operações similares de banco de dados em vários locais e em vários apresentadores, por exemplo, adquirindo os mais novos artigos publicados. Se melhorarmos nossa aplicação adicionando uma bandeira aos artigos para indicar um estado de trabalho em andamento, devemos também passar por todos os locais em nossa aplicação e adicionar uma cláusula de localização para garantir que apenas os artigos acabados sejam selecionados.

Neste ponto, o trabalho direto com o banco de dados torna-se insuficiente e será mais inteligente nos ajudar com uma nova função que retorna artigos publicados. E quando adicionamos outra cláusula posteriormente (por exemplo, para não exibir artigos com uma data futura), editamos nosso código apenas em um lugar.

Colocaremos a função na classe PostFacade e a chamaremos de getPublicArticles().

Vamos criar nossa classe modelo PostFacade no diretório app/Model/ para cuidar de nossos artigos:

<?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');
	}
}

Na classe passamos no Explorer do banco de dados. Isto irá tirar proveito do poder do recipiente DI.

Mudaremos para HomePresenter que editaremos para nos livrarmos da dependência em Nette\Database\Explorer, substituindo-a por uma nova dependência de nossa nova classe.

<?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);
	}
}

Na seção de uso, estamos usando App\Model\PostFacade, assim podemos encurtar o código PHP para PostFacade. Solicitamos este objeto no construtor, escrevemo-lo na propriedade $facade e o usamos no método renderDefault.

O último passo restante é ensinar o recipiente DI a produzir este objeto. Isto geralmente é feito adicionando um ponto no arquivo config/services.neon na seção services, dando o nome completo da classe e os parâmetros do construtor. Isto o registra, por assim dizer, e o objeto é então chamado de **service***. Graças a alguma mágica chamada autowiring, normalmente não precisamos especificar os parâmetros do construtor porque DI os reconhecerá e os passará automaticamente. Assim, seria suficiente apenas fornecer o nome da classe:

...

services:
	- App\Model\PostFacade

Entretanto, você também não precisa acrescentar esta linha. Na seção search no início de services.neon está definido que todas as classes que terminem com -Facade ou -Factory serão pesquisadas automaticamente por DI, o que também é o caso de PostFacade.

Sumário

A classe PostFacade pede Nette\Database\Explorer em um construtor e como esta classe está registrada no container DI, o container cria esta instância e a passa. DI desta forma cria uma instância PostFacade para nós e a passa em uma construtora para a classe HomePresenter que a solicitou. Uma espécie de boneca Matryoshka de código :) Todos os componentes só pedem o que precisam e não se importam onde e como ele é criado. A criação é feita por um recipiente DI.

Aqui você pode ler mais sobre injeção de dependência, e sobre configuração.