mercoledì 23 luglio 2014

Soft delete con Symfony2

Può capitare di dover implementare un sistema di soft delete nella propria applicazione web.

Niente di più semplice con queste estensioni di doctrine.

Per installare il bundle basta seguire le istruzioni.

Una volta installato é necessario modificare in questo modo la configurazione di doctrine nel file # app/config/config.yml
# Doctrine Configuration
doctrine:
    dbal:
        driver:   "%database_driver%"
        host:     "%database_host%"
        port:     "%database_port%"
        dbname:   "%database_name%"
        user:     "%database_user%"
        password: "%database_password%"
        charset:  UTF8
    orm:
        auto_generate_proxy_classes: "%kernel.debug%"
        auto_mapping: true
        filters:
            softdeleteable:
                class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter
                enabled: true

Solo le ultime 4 righe sono da aggiungere, le altre dovrebbero essere già presenti nel file di configurazione.


Sempre nel file # app/config/config.yml aggiungiamo le righe:

stof_doctrine_extensions:
    orm:
        default:
            softdeleteable: true

Ora non ci rimane che andare a modificare l'entity per la quale vogliamo utilizzare il soft delete.

Apriamo il file dell'entity, ad esempio # src/Acme/UserBundle/Entity/User.php.

Aggiungiamo prima della classe
use Gedmo\Mapping\Annotation as Gedmo;

La riga seguente invece va inserita tra i commenti, sempre prima della classe

 /*
 * @Gedmo\SoftDeleteable(fieldName="deletedAt")
 */

come ultima cosa aggiungiamo il campo che farà la differenza tra un record cancellato e uno ancora in uso.

    /**
     * @var \DateTime $deletedAt
     *
     * @ORM\Column(name="deleted_at", type="datetime", nullable=true)
     */
    private $deletedAt;


La classe dovrebbe essere più o meno così



namespace Acme\UserBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Gedmo\Mapping\Annotation as Gedmo; 
/**
 * @Gedmo\SoftDeleteable(fieldName="deletedAt")
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @var \DateTime $deletedAt
     *
     * @ORM\Column(name="deleted_at", type="datetime", nullable=true)
     */
    private $deletedAt; 

    public function __construct()
    {
        parent::__construct();
        // your own logic
    }


     
Il sistema fa tutto da solo, non c'é bisogno di modificare nient'altro, né le chiamate per cancellare le entity ->remove($user) né le query per selezionare i dati. Tra l'altro, se sono presenti delle relazioni tra tabelle (scritte correttamente) e se le query sono scritte bene, viene aggiornato tutto automaticamente.

1 commento:

  1. Salve, grazie per la completa descrizione del soft delete e sopratutto per il titolo della pagina "CHE PALLE", molto azzeccato. Difatti mi trovo ad affrontare un problema con il soft delete e chiedo se puoi aiutarmi. Il problema è il seguente:
    il soft delete mi funziona, ma essendo che nel database il record rimane sempre e comunque, dovrei in qualche modo evitare che le altre classi chiamino proprio questo record. COME FACCIO?

    RispondiElimina