2009-10-19 6 views
3

Dans mon application CakePHP 1.2.5, j'ai un modèle Profile qui appartient à un modèle User. Le modèle User a un champ username et lors de l'exécution d'un find() sur le modèle Profile, je souhaite toujours récupérer automatiquement la valeur de User.username. Je suppose qu'il serait logique de modifier la méthode beforeFind() de mon modèle de profil pour contenir automatiquement le champ désiré.Modification des champs Containable requis dans le rappel beforeFind?

Voici ce que je tentais de le faire:

public function beforeFind($queryData) { 
    // determine if the username data was already requested to be included in the return data via 'User.username' or 'User' => array('username'). 
    $hasUserData = isset($queryData['contain']) && in_array("User.{$this->User->displayField}", $queryData['contain']); 
    $hasUserData |= isset($queryData['contain']['User']) && in_array($this->User->displayField, $queryData['contain']['User']); 

    // request the the username data be included if it hasn't already been requested by the calling method 
    if (!$hasUserData) { 
     $queryData['contain']['User'][] = $this->User->displayField; 
    } 

    return $queryData; 
} 

Je peux voir que la valeur de $queryData['contain'] est correctement mis à jour, mais les données de nom d'utilisateur n'est pas récupéré. J'ai regardé dans le code de base de CakePHP pour la méthode find(), et j'ai trouvé que le rappel beforeFind() est appelé après tous les rappels de Behaviors, signifiant que Containable a déjà fait ce qu'il avait besoin de faire avec la valeur de $queryData['contain'] avant que je puisse le modifier .

Comment est-ce que je peux contourner ceci sans hacker le noyau?

Répondre

6

Je l'ai résolu, alors voici ma réponse au cas où quelqu'un aurait la même complication. Les champs conteneurables ne peuvent pas être spécifiés dans beforeFind car toutes les méthodes beforeFind() de Behaviors sont appelées avant à la méthode beforeFind() du modèle.

En tant que tel, il était nécessaire pour moi de modifier la méthode find() directement sur le modèle Profile afin d'ajouter mon champ conteneurable personnalisé.

public function find($conditions = null, $fields = array(), $order = null, $recursive = null) { 
    $this->contain("{$this->User->alias}.{$this->User->displayField}"); 
    return parent::find($conditions, $fields, $order, $recursive); 
} 
+0

Merci! Je me demandais aussi si la modification de beforeFind() était "trop ​​tard". En effet, c'était. – Wayne

1

Matt, je crois que c'est une bonne solution. J'utilise CakePHP 2.0.4 et j'avais l'intention de récupérer uniquement les données du modèle utilisateur.

Juste pour l'enregistrement, la mise en actsAs pour le modèle utilisateur

class User extends AppModel { 
    public $name = 'User'; 
    public $belongsTo = array('Role'); 
    public $actsAs = array('Containable'); 
    ... 

Puis-je remplacer la méthode de découverte de cette façon:

public function find($conditions = null, $fields = array(), $order = null, $recursive = null) { 
    $this->contain(); 
    return parent::find($conditions, $fields, $order, $recursive); 
} 

Ou, si l'intention de récupérer les données profil, par exemple:

public function find($conditions = null, $fields = array(), $order = null, $recursive = null) { 
    $this->contain(array('Profile')); 
    return parent::find($conditions, $fields, $order, $recursive); 
} 
Questions connexes