HABTM: l’associazione HasAndBelongToMany

Questa associazione gestisce la classica relazione “molti-a-molti”, tipo quella che si può creare tra due oggetti quali “Articles” e “Keywords”.
Ogni articolo può avere associate più parole chiave e una parola chiave può essere associata a più articoli.

Supponiamo di disporre già delle tabelle articles e keywords.
Sarà necessario creare la tabella di join che permetta la relazione “molti-a-molti” tra le due tabelle.
Per convenzione in CakePHP questa tabella assumerà un nome che viene ricavato dai nomi delle due tabelle implicate ordinati alfabeticamente, separate da un carattere underscore ( _ ).

Nel nostro caso la join table verrà chiamata articles_keywords e avrà come unici campi le due chiavi esterne che fanno riferimento alla convenzione CakePHP: “article_id” e “keyword_id” che formeranno la chiave primaria della tabella.

Il passo successivo è quello di definire l’associazione nel model relativo agli articoli

var $hasAndBelongsToMany = array('Keyword' =>
                 array('className'    => 'Keyword',
                          'joinTable'    => 'articles_keywords',
                          'foreignKey'   => 'article_id',
                          'associationForeignKey'=> 'keyword_id',
                          'conditions'   => '',
                          'order'        => 'Keyword.keyword ASC',
                          'limit'        => '',
                          'unique'       => true,
                          'finderQuery'  => '',
                          'deleteQuery'  => '',
                  );

‘joinTable’ è la tabella di join che abbiamo creato e ‘foreignKey’ e ‘associationForeignKey’ rappresentano i campi relative alle chiavi.
Secondo il manuale di CakePHP non sarebbe necessario specificare il nome dei campi se si rispettano le convenzioni.

Salvare i dati

Poniamo il caso che abbiamo un articolo già inserito nella tabella Articles (ma se non è ancora presente fa lo stesso) al quale vogliamo associare delle keyword da prelevare dalla tabella Keywords.

La procedura da seguire è semplicemente la seguente:

1. Si popola l’array $this->data con i valori da inserire.

L’array deve contenere i dati dell’articolo e quelli delle keyword da associare all’articolo. In particolare i dati relativi alla tabella associata devono avere un particolare formato.
Quindi immaginiamo di avere $this->data già popolato da un form compilato e inviato dall’utente che appare come segue:

Array
(
    [Article] => Array
        (
            [id] => 4
            [category_id] => 12
            [titolo] => Questo è il titolo dell'articolo
            [sottotitolo] => Sottotitolo
            [testo] => Bla bla bla bla bla bla bla bla bla bla bla
            [user_id] => 0
            [created] => 2007-03-02 08:16:44
            [modified] => 2007-03-06 14:00:45
            [data_pub] => 
            [data_fine_pub] => 
            [onindex] => 0
            [pubblicato] => 0
        )

    [Category] => Array
        (
            [descrizione] => Novità
        )

    [Keyword] => Array
        (
            [0] => Array
                (
                    [id] => 2
                    [keyword] => aids
                )

            [1] => Array
                (
                    [id] => 9
                    [keyword] => bambini
                )

            [2] => Array
                (
                    [id] => 8
                    [keyword] => fame
                )

            [3] => Array
                (
                    [id] => 4
                    [keyword] => popolazioni
                )

        )

)

A questo punto bisogna impostare l’elemento

$this->data['Keyword'] = array('Keyword' => array ( 23, 56, 67));

dove 23, 56 e 67 rappresentano l’id delle keyword da associare.
Volendo riscrivere l’array nel formato indicato dal manuale si può dire che l’array avrà un formato del tipo

['Keyword']['Keyword'][23]
['Keyword']['Keyword'][56]
['Keyword']['Keyword'][67]

2. Si invoca il metodo save del modello Article.

In questo modo si può salvare l’intero articolo e associare le keyword selezionate.

Per un passaggio più stringato basta impostare il seguente array
$data = array (‘Article’ => array(‘id’ => 4) ,
‘Keyword’ => array(‘Keyword’ => array (23,56,67))
)

Questo è sufficente per eseguire la sola associazione delle keyword

Quando le cose si fanno complicate
Sicuramente capiterà di dover gestire la relazione many-to-many impostando delle informazioni aggiuntive circa l’associazione, tipo la data di creazione dell’associazione (ad esempio l’associazione Users-Groups).
Per questa problematica è utilissimo leggere un post di ThinkingPHP and beyond che tratta l’argomento nei particolari:

Modeling relationships in CakePHP (faking Rails ThroughAssociation)

Un altro articolo interessante:

ThroughAssociations

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.