How to remove associations on the fly in CakePHP v3

In previous versions of CakePHP, you could temporarily change associations with Table::bindModel('SomeModel'); but I can't figure out how to do this in v3.

I want to temporarily disable the hasMany association defined in the Table class, because it causes errors when performing old migrations that were written before this table existed. I do not quite understand the migration problem, but it disappears immediately when I comment on the association in the Table class.

 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
source share
1 answer

The problem is that when using migration, you should not rely on actual model classes. This can lead to exactly the problem you are facing.

Instead, use a TableRegistry or Table object, and create a table object without any dependencies. Download the associations you need directly at this facility.

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

This way, migration will work no matter what other changes have been made to your AgenciesTable class. And this is IMHO the right way to do this when migrating.

I think that even if you do not create the association explicitly by calling $this->hasMany('Routes'); , you will get the same error because the bootloader will still try to find the corresponding table class and load it dynamically. This is also the reason for the lack of a "non-configuration" method.

Also you are not showing your actual request code ... Therefore, I assume that you are calling a custom search or method that calls Query :: contain () somewhere. Just write a new request without this?

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

If you have a large query, it might be a good idea to split it into more custom finds, because they can be combined:

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

See Custom Search Methods .

+1
source

All Articles