6 votes

Comment supprimer une association en vol dans CakePHP v3

Dans les versions précédentes de CakePHP, vous pouviez temporairement modifier des associations avec Table::bindModel('SomeModel'); mais je ne parviens pas à comprendre comment le faire en v3.

Je souhaite temporairement désactiver une association hasMany définie dans la classe Table car elle provoque des erreurs lorsque j'exécute d'anciennes migrations qui ont été écrites avant l'existence de cette table. Je ne comprends pas pleinement le problème de migration mais il disparaît immédiatement lorsque je commente l'association dans la classe Table.

class AgenciesTable extends Table
{
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->table('agencies');
        $this->displayField('full_name');
        $this->primaryKey('id');
        $this->addBehavior('Timestamp');

        $this->hasMany('Routes');

entrer la description de l'image ici

1voto

burzum Points 10445

Le problème ici est que vous ne devriez pas vous fier aux classes de modèle réelles lors de l'utilisation de migrations. Cela peut entraîner exactement le type de problème que vous venez de rencontrer.

Utilisez plutôt TableRegistry ou un objet Table directement et créez un objet table sans aucune dépendance. Chargez directement les associations dont vous avez besoin sur cet objet.

$agences = new Table(['table' => 'agences', /*...*/]);
$agences->belongsTo('Quelquechose');
/* Effectuez votre manipulation de données */

Ainsi, la migration fonctionnera peu importe les autres modifications apportées à votre classe AgenciesTable. Et c'est à mon humble avis la bonne manière de le faire dans les migrations.

Je pense que même si vous ne créez pas explicitement l'association en appelant $this->hasMany('Routes'); vous finirez par obtenir la même erreur car le chargeur impatient tentera toujours de trouver une classe de table correspondante et de la charger dynamiquement. C'est aussi la raison pour laquelle il n'y a pas de méthode "uncontain".

De plus, vous ne montrez pas votre code de requête actuel... Donc je suppose que vous appelez une recherche personnalisée ou une méthode qui appelle Query::contain() quelque part. Écrivez simplement une nouvelle requête sans ce contain ?

$agences->find()->contain(['Un', 'Deux'])->where([/*...*/])->all();

Si vous avez une grande requête, il peut être judicieux de la diviser en plus de recherches personnalisées car elles peuvent être combinées :

$agences->find('sansMonContain')->all();
$agences->find('sansMonContain')->find('avecMonContain')->all();

Voir Méthodes de Recherche Personnalisées.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X