La comunità italiana su CakePHP

You are not logged in. Please login or register.


Pages: 1

Atom RSS

Posts [ 4 ]

zuck

Topic: Relazioni hasOne - belongsTo e implementazione ereditarietà

Salve di nuovo a tutti. Il quesito di questa volta riguarda un mio tentativo di implementare un meccanismo di specializzazione tra alcuni modelli.

Lo scenario è il seguente:

1) Immaginiamo di avere una classe di modello chiamata "Attachment" con attributi:

  - id
  - name -> pathname completo (dir + filename) del file sul server.
  - type -> tipologia MIME del file.
  - size -> Dimensione in bytes del file.

2) Immaginiamo ora di specializzare questa classe in un altro modello, ad esempio "Image". Questo modello "specializzato" non verrà costruito tramite i costrutti di ereditarietà della programmazione OOP, bensì ho pensato di implementarlo tramite un'associazione ER "uno-a-uno" con il modello "Attachment". In particolare il modello "Image" è così definito:

  - id
  - attachment_id -> "istanza" di attachment che quest'istanza di "Image" specializza.
  - alt -> descrizione alternativa.
  - width
  - height

3) L'associazione è così definita:

    //models/image.php

    /**
     * Un'immagine è una specializzazione di un generico allegato.
     */
    var $belongsTo = 'Attachment';

La cosa interessante di questo sistema è che, ad esempio, nella mia applicazione ogni allegato può essere "taggato" (così come le pagine) e questo permette di implementare un meccanismo di ricerca basato su tags rapido e completo (soprattutto usando il "behavior" che ho postato nel thread sulle HABTM).

Tale comportamento è inserito nel modello "Behavior" e, di conseguenza, viene "ereditato" in tutte le classi che implementano questa sorta di "specializzazione". Inoltre, come è ovvio, tutti i dettagli di più basso livello (nome, dimensione in bytes, tipo, ecc.) sono incapsulati in "Attachment" rendendo i modelli specializzati più piccoli e leggeri.

Avendo poi anche "controllers" separati è possibile centralizzare l'upload degli "attachments" (usando uno dei tanti componenti già pronti) ed estendendo di volta in volta il form con gli eventuali campi aggiuntivi del modello che si vuole caricare.

Non tutti gli "attachments", poi, possono avere bisogno di una gestione specializzata, rendendo così il sistema più flessibile, concentrandosi solo sui tipi di files che richiedono operazioni specifiche (ad esempio le immagini).



Bene. Ora veniamo ai problemi.... wink Il problema fondamentale è uno: come riuscire ad associare sempre il file "genitore" al modello specializzato in qualunque operazione che lo riguarda? Io avevo pensato di ricorrere ad un "behavior" chiamato "Allegeable" utilizzato dalle varie classi specializzate con, implementato, il metodo "afterFind":

<?php 

/**
 * Allegeable Behavior class file.
 *
 * Model Behavior to support attachment specialization.
 *
 * @author        Emanuele 'Zuck' Bertoldi
 * @filesource
 * @package       app
 * @subpackage    models.behaviors
 */
class AllegeableBehavior extends ModelBehavior {
    
    /**
     * Initiate behaviour for the model using specified settings.
     *
     * @param object $model    Model using the behaviour
     * @param array $settings    Settings to override for model.
     *
     * @access public
     */
    function setup(&$model, $settings = array()) {

        $default = array('attachment_model_name' => 'attachment');
        
        if (!isset($this->settings[$model->name])) {
            
            $this->settings[$model->name] = $default;
        }
        
        $this->settings[$model->name] = array_merge($this->settings[$model->name], ife(is_array($settings), $settings, array()));
    }

    /**
     * Run after a model is found, used to fill parent model attachment data.
     *
     * @param object $model    Model about to be found.
     * @param mixed $results   Model rows found.
     *
     * @access public
     * @since 1.0
     */
    function afterFind(&$model, &$results) {
        
        if (!empty($results)) {
            
            $parent_model_name = $this->settings[$model->name]['attachment_model_name'];
            $model_ref_name = $parent_model_name.'_id';
            
            $p =& new $parent_model_name;
            
            foreach ($results as &$m) {
                
                $m[$parent_model_name] = $p->read(null, $m[$model->name][$model_ref_name]);
            }
        }
    }
}

?>

Questo sistema funziona solo in alcuni casi, in particolare ho riscontrato che nel seguente caso non viene invocato:

- Leggo i dati di una riga della tabella "Page" che possiede una relazione "belongsTo" con "Image". L'array restituito si ferma ad "Image" e non allega anche i dati di "Attachment" (infatti il metodo del behavior non viene invocato).

Il problema potrebbe essere nel "recursive" che deve essere maggiore di "1" per invocare anche "Attachment"? E se questo accorgimento funziona con le operazioni di "find", come sistemo la faccenda anche quando richiedo i dati tramite paginazione? In questo caso questo parametro dove lo imposto?


Grazie per l'eventuale aiuto!! wink

zuck

Re: Relazioni hasOne - belongsTo e implementazione ereditarietà

Dunque, sto risolvendo agendo manualmente sulle varie impostazioni "recursive" dei modelli (così non serve specificarle nei vari "find").

Inoltre ho eliminato l'associazione "hasMany" da "Image" (relativo a "Page"). In questo modo impostando a '3' la ricorsione su "Page" alla fine ottengo il seguente albero:

    /**
     * Ricorsione:
     * 
     * Page
     * |____ User
     * |      |____ Profile
     * |      |____ Page
     * |
     * |____ Image 
     * |      |____ Attachment
     * |
     * |____ Tag 
     *        |____ Attachment
     *        |____ Page
     */

Tuttavia vorrei trovare un modo sistematico per presentare sempre insieme ai modelli specializzati (come "Image") anche il relativo "genitore" del modello "Attachment"...

Il behavior ho visto che alla fine è superfluo per questa operazione.

zuck

Re: Relazioni hasOne - belongsTo e implementazione ereditarietà

Nessuno può aiutarmi? wink

Namaless

Re: Relazioni hasOne - belongsTo e implementazione ereditarietà

zuck wrote:

Nessuno può aiutarmi? wink

Il sistema di associazioni è una cosa complessa.. tu hai realizzato qualcosa di complesso... quindi "complesso + complesso = da studiare" smile

Nei prossimi giorni devo studiare le novità su CakePHP 1.2 e lascerò maggiori informazioni nelle discussioni inerenti a problematiche.

Considerando poi che non sono una cima con CakePHP ci vorrà un pò di tempo/pazienza.. Saiborg ne sà molto più di me, magari attendiamo un suo responso big_smile

Posts [ 4 ]

Guest posting is disabled. You must login or register to post a reply.

Pages: 1

Topic info

0 guests and 0 users are reading this topic now


Forum quick jump menu

Currently used extensions: pun_topic_online_users, pun_karma, pun_admin_hook_navigator, pun_bbcode. Copyright © 2008 PunBB

[ Generated in 0.043 seconds, 12 queries executed ]