Pregunta Cómo eliminar una asociación sobre la marcha en CakePHP v3


En versiones anteriores de CakePHP, podía alterar temporalmente las asociaciones con Table::bindModel('SomeModel'); pero no puedo entender cómo hacerlo en v3.

Deseo desactivar temporalmente una asociación hasMany que está definida en la clase Table porque está causando errores cuando ejecuto migraciones anteriores que se escribieron antes de que existiera esa tabla. No entiendo completamente el problema de migración, pero desaparece inmediatamente cuando comento la asociación en la clase 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');

enter image description here


6
2017-09-01 22:50


origen


Respuestas:


El problema aquí es que deberías no confíe en las clases reales del modelo cuando usa migraciones. Esto puede causar exactamente el tipo de problema que acabas de encontrar.

En su lugar, use el TableRegistry o un objeto Table directamente y cree un objeto de tabla sin dependencias. Cargue las asociaciones que necesita directamente en ese objeto.

$agencies = new Table(['table' => 'agencies', /*...*/]);
$agencies->belongsTo('Whatever');
/* Do your data manipulation */

De esta forma, la migración funcionará sin importar qué otros cambios se hayan realizado en su clase AgentsTable. Y esto es en mi humilde opinión la forma correcta de hacerlo en migraciones.

Creo que incluso si no creas explícitamente la asociación llamando $this->hasMany('Routes'); terminará con el mismo error porque el cargador impaciente aún intentará encontrar una clase de tabla coincidente y cargarlo dinámicamente. Esta es también la razón por la cual no hay un método "incontestable".

Además, no está mostrando su código de consulta real ... Así que asumir está llamando a un hallazgo o método personalizado que llama a Query :: contain () en algún lugar. ¿Simplemente escribe una nueva consulta sin que contenga?

$agencies->find()->contain(['One', 'Two'])->where([/*...*/])->all();

Si tiene una gran consulta, puede ser una buena idea dividirla en más hallazgos personalizados porque se pueden combinar:

$agencies->find('withoutMyContain')->all();
$agencies->find('withoutMyContain')->find('withMyContain')->all();

Ver Métodos de búsqueda personalizada.


1
2017-09-02 10:00