микрозаймы онлайн займы на карту займы по паспорту

Laravel e a facilidade do “soft deleting” 18

Normalmente no desenvolvimento de aplicações empresariais e de larga escala nas quais se utiliza banco de dados, é solicitado que nenhum registro persistido no mesmo seja removido definitivamente, afim de que possa-se obter relatórios completos e um histórico de informações, o que inclui os registros que foram tidos como “removidos”. Para isso, muitas vezes (ou todas) utilizamos uma coluna de controle em tabelas do banco de dados, um valor booleano, que estará com o valor true para um registro “existente” e false para um registro que foi “apagado”.

Logo, em nas buscas executadas para registros “existentes” devemos levar em consideração apenas os que estão com o valor da coluna de controle como true o que, querendo ou não, traz um pouco mais de trabalho para o desenvolvimento das buscas e até para o processo de “remoção” de registros; a operação “delete” de um CRUD tem que ser modificada para apenas atualizar o valor da coluna de controle do registro. Se tratando de ORM’s, como a maioria não provê esta funcionalidade “out-of-the-box”, o trabalho pode ficar um pouco maçante.

Pensando nisso, o sensacional Laravel em sua versão 4 traz uma ótima feature para poupar este trabalho, chamada soft deleting. A mesma adiciona uma coluna para as tabelas que possuem a feature chamada deleted_at, um timestamp que servirá para determinar se o registro foi ou não “removido”. Para que a mesma possa ser usada, o primeiro passo é adicionar uma propriedade chamada softDelete no model que terá a feature, da seguinte forma:

class Post extends Eloquent {

    protected $softDelete = true;

}

Devemos também adicionar o método softDeletes() na migração da tabela “posts” para que a mesma possa criar a coluna deleted_at. Faremos isso da seguinte maneira:

Schema::create('posts', function($table)
{
    $table->increments('id');
    $table->string('title');
    $table->integer('views');
    $table->text('body')

    $table->timestamps();
    $table->softDeletes();
});

Com essas adições, toda vez que o método delete() for invocado em nosso model Post, o mesmo não será excluído da tabela e sim, sua coluna deleted_at será modificada com o timestamp de sua “remoção”. Nas buscas efetuadas no model, todos os registros que possuírem valor nesta coluna não serão adicionados no resultado como se, de fato, fossem inexistentes na base de dados.

Porém, como tudo no Laravel, nada é imposto e podemos efetuar a busca trazendo também os registros “excluídos”, utilizando o método withTrashed() no model, da seguinte forma:

Post::withTrashed()->where('views', '>', '1000');

Da mesma forma, podemos efetuar buscas apenas em registros que foram “excluídos”, através do método onlyTrashed():

Post::onlyTrashed()->where('views', '>', '1000');

Além disso, podemos restaurar um registro para o estado “ativo”, o que o retornará nas buscas, como se o mesmo não tivesse sido “excluído” através do método restore():

// Utilizando restore() em uma instância de post (um registro)
$post->restore();

// Utilizando restore() no retorno de uma busca
Post::withTrashed()->where('views', '>', '1000')->restore();

// Podemos utilizar restore() para coleções que pertencem ao model
$post->comments()->restore();

Novamente, se tratando da flexibilidade do Laravel, o mesmo provê um meio para que o registro seja, de fato, excluído permanentemente do banco de dados. Basta utilizar o método forceDelete():

// Excluirá o registro permanentemente da base de dados
$post->forceDelete();

// Podemos utilizar forceDelete() para coleções que pertencem ao model
$post->comments()->forceDelete();

E, por fim mas não menos importante, para verificarmos se um registro foi “excluído”, podemos utilizar o método trashed() que retornará um booleano indicando se o registro está ou não inativo (está ou não com a coluna deleted_at preenchida):

if ($post->trashed()) {
  // Está inativo no banco de dados =P
}

Para quem já teve que reproduzir este comportamento em aplicações (meu caso), é realmente uma “mão na roda” o soft deleting que o Laravel provê. Não polui o código, não requer hacking e de verdade, é uma feature muito bem implementada. O Laravel como sempre mostrando que é um Framework pensado nos mais comuns problemas enfrentados por nós, desenvolvedores Web.

Clean code it ! =P

  • cironunes

    Feature incrível!

    Parabéns pelo artigo, simples e útil.
    []s

  • Sal

    Parabéns pelo post, Guilherme!

  • Rodrigo Queiroz

    ótimo post, thanks.

  • João Paulo

    Muito bom!

  • Hélio

    Bem útil! Eles criaram uma `dsl` para algo deveras utilizado.

  • Julio Bitencourt

    Fantástico! No CodeIgniter eu fiz uma extensão do CI_Model para simular este comportamento. Mas no laravel fica muito mais flexível!

    • Guilherme Franco

      Exatamente, o ponto chave é a funcionalidade out-of-the-box =P

  • fhferreira

    Excelente Post Brayan essa feature foi muito bem pensada, não cheguei a usa-la ainda.

    Vlw pela contribuição.

    • http://brayanrastelli.com/ Brayan Rastelli

      Na verdade não fui eu quem fez o post heheh.. mas é muito útil mesmo.. já usei em meu projeto =)

      Abs.

  • http://www.aprendda.com/ Renato Tavares

    Parabéns, ótimo artigo.

    Que dia rola um de queues? todos querem isso!

    • Guilherme Franco

      Opa Renato !

      Pode deixar que prepararei um para breve. Tive experiência com background jobs há pouco tempo. Pode aguardar !

      • http://www.aprendda.com/ Renato Tavares

        Estou esperando mesmo!

  • julio

    Muito bom, não conhecia.

  • rodurma

    Tinha visto isso nas documentações e achei sensacional. Ótimo artigo.
    [ ]’s

  • Cristiano Franco

    Muito bom, mas e como ficam a integridade relacional de outras tabelas?

    • Rupert Lustosa

      Cristiano, integridade relacional não será afetada… Esse conceito é voltado para que não se corra riscos de possuir registros orfãos na base de dados. Como vc deve saber, um pai não pode ser removido se ele possuir filhos. Com o soft delete nós não removemos nada… então não criaremos nada orfão. O que pode ocorrer dependendo da sua lógica é um registro filho ainda ser exibido em alguma tela, mas aí vai depender do seu código, mas esse filho ainda possui um pai na base de dados. Abraços

      • Cristiano Franco

        Amigo, obrigado pela resposta.
        Eu queria saber se os “filhos” tb sofrem soft-deleting quando um registro pai sofrer.

  • Assunção Jr

    Muito bom o artigo, porém sugiro que o mesmo deve ser atualizado, visto que a forma de utilização é diferente da informada aqui – vide documentação http://laravel.com/docs/4.2/eloquent#soft-deleting