Hi, I’m developing my app with Cakephp 3.5.11, the current version
I have the tables sell_regions (inside plugin Sell), countries and provinces (outside plugins), and these are its Tables:
plugins/Sell/Model/Table/RegionsTable.php:
class RegionsTable extends Table {
public function initialize(array $config) {
parent::initialize($config);
$this->setTable('sell_regions');
$this->belongsToMany('Countries', [
'joinTable' => 'sell_countries_regions'])
->setForeignKey('region_id');
$this->belongsToMany('Provinces', [
'joinTable' => 'sell_provinces_regions'])
->setForeignKey('region_id');
$this->addBehavior('Timestamp');
}
src/Model/Table/CountriesTable.php:
class CountriesTable extends Table {
public function initialize(array $config) {
parent::initialize($config);
$this->hasMany('Provinces')
->setDependent(true)
->setCascadeCallbacks(true)
->setSort(['Provinces.title' => 'asc']);
$this->belongsToMany('Sell.Regions', [
'joinTable' => 'sell_countries_regions'])
->setTargetForeignKey('region_id');
$this->addBehavior('Timestamp');
}
src/Model/Table/ProvincesTable.php:
class ProvincesTable extends Table {
public function initialize(array $config) {
parent::initialize($config);
$this->belongsTo('Countries');
$this->belongsToMany('Sell.Regions', [
'joinTable' => 'sell_provinces_regions'])
->setTargetForeignKey('region_id');
$this->addBehavior('Timestamp');
}
plugins/Sell/Template/Regions/edit.ctp:
<?= $this->Form->create($region);?>
<?= $this->Form->control('countries._ids', ['label' => __('Countries')]);?>
<?= $this->Form->control('provinces._ids', ['label' => __('Provinces')]);?>
<?= $this->Form->control('title', ['label' => __('Title')]);?>
<?= $this->Form->button(__('Save changes'), ['type' => 'submit']);?>
<?= $this->Form->end();?>
plugins/Sell/Controller/RegionsController.php:
public function edit($id = null) {
$region = $this->Regions->get($id, [
‘contain’ => [
‘Countries’ => function (\Cake\ORM\Query $query) { return $query->select([‘id’]); },
‘Provinces’ => function (\Cake\ORM\Query $query) { return $query->select([‘id’]); }
]
]);
if ($this->request->is([‘patch’, ‘post’, ‘put’])) {
$region = $this->Regions->patchEntity($region, $this->request->getData());
debug($region);
if ($this->Regions->save($region)) {
$this->Flash->success((‘Changes saved’));
return $this->redirect([‘action’ => ‘view’, $region->id]);
} else {
$this->Flash->error((‘Changes not saved. Please, try again.’));
//$this->Flash->error(json_encode($region->errors()));
}
}
$countries = $this->Regions->Countries->find(‘list’, [‘order’ => ‘title’]);
$provinces = $this->Regions->Provinces->find(‘list’, [‘order’ => ‘title’]);
$this->set(compact(‘region’, ‘countries’, ‘provinces’));
}
debug($region) shows:
object(Ventas\Model\Entity\Region) {
'id' => '779da13e-3ea4-428b-97b3-c0d8b34c47ce',
'title' => 'Near',
'created' => object(Cake\I18n\FrozenTime) {
'time' => '2018-01-23T15:28:55+01:00',
'timezone' => 'Europe/Madrid',
'fixedNowTime' => false
},
'modified' => object(Cake\I18n\FrozenTime) {
'time' => '2018-02-06T14:04:47+01:00',
'timezone' => 'Europe/Madrid',
'fixedNowTime' => false
},
'provinces' => [
(int) 0 => object(App\Model\Entity\Province) {
'id' => (int) 15,
'title' => 'A Coruña',
'pais_id' => (int) 73,
'hc_key' => 'es-c',
'created' => object(Cake\I18n\FrozenTime) {
'time' => '1970-01-01T00:00:00+01:00',
'timezone' => 'Europe/Madrid',
'fixedNowTime' => false
},
'modified' => object(Cake\I18n\FrozenTime) {
'time' => '1970-01-01T00:00:00+01:00',
'timezone' => 'Europe/Madrid',
'fixedNowTime' => false
},
'[new]' => false,
'[accessible]' => [
'*' => true,
'id' => false
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Provinces'
}
],
'countries' => [
(int) 0 => object(App\Model\Entity\Country) {
'id' => (int) 2,
'title' => 'Afganistán',
'isonum' => (int) 4,
'iso2' => 'AF',
'iso3' => 'AFG',
'created' => object(Cake\I18n\FrozenTime) {
'time' => '1970-01-01T00:00:00+01:00',
'timezone' => 'Europe/Madrid',
'fixedNowTime' => false
},
'modified' => object(Cake\I18n\FrozenTime) {
'time' => '1970-01-01T00:00:00+01:00',
'timezone' => 'Europe/Madrid',
'fixedNowTime' => false
},
'[new]' => false,
'[accessible]' => [
'*' => true,
'id' => false
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Countries'
}
],
'[new]' => false,
'[accessible]' => [
'*' => true,
'id' => false
],
'[dirty]' => [
'countries' => true,
'provinces' => true
],
'[original]' => [
'countries' => [
(int) 0 => object(App\Model\Entity\Country) {
'id' => (int) 2,
'_joinData' => object(Cake\ORM\Entity) {
'id' => 'd78a21ca-9d36-47dc-82ba-c8c1d2de18ae',
'country_id' => '2',
'region_id' => '779da13e-3ea4-428b-97b3-c0d8b34c47ce',
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'SellCountriesRegions'
},
'[new]' => false,
'[accessible]' => [
'*' => true,
'id' => false
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Countries'
}
],
'provinces' => [
(int) 0 => object(App\Model\Entity\Province) {
'id' => (int) 15,
'_joinData' => object(Cake\ORM\Entity) {
'id' => '59c875cc-6485-4947-bf05-8912017664ee',
'province_id' => '15',
'region_id' => '779da13e-3ea4-428b-97b3-c0d8b34c47ce',
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'SellProvincesRegions'
},
'[new]' => false,
'[accessible]' => [
'*' => true,
'id' => false
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Provinces'
}
]
],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Sell.Regions'
}
When I edit a Region and I dont change any Country or Province, app creates a new registry in SellCountriesRegions or SellProvincesRegions.
I`ve created many associations like these in other apps without problems. But this time, I don’t find the error or problem.