CakePHP 3.0 association being marked as dirty when it's actually clean

1.4k views Asked by At

I'm trying to Update/Save TradingPartner Entities (Customers and Suppliers) that can have many Addresses associated (TradingPartnerAddresses).

I have an array of changed TradingPartners and i'm using Cake's patchEntities() function to merge the existing records with the modified ones.

The issue is that Cake is incorrectly marking the associated addresses as dirty and when looping through the Entities to save them it's trying to re-insert the existing addresses - causing duplicate addresses.

Here's the code:

Trading Partners Controller

//Load the trading partners model
$tradingPartners = TableRegistry::get('TradingPartners');

//find all existing trading partners and their associated addresses
$currentTradingPartners = $tradingPartners->find('all')
                                     ->contain(['TradingPartnerAddresses']);

//Patch trading partner changes
//Cake automagically handles 1 level of associations
$patchedTpEntities = $tradingPartners->patchEntities($currentTradingPartners, $partners);

//loop through and save all dirty fields
foreach ($patchedTpEntities as $tpEntity) {
   if ($tradingPartners->save($tpEntity)) {
   } else {
      //TODO
   }
}

Trading Partners Table

public function initialize(array $config) {
    $this->primaryKey('partner_code');

    $this->hasMany('TradingPartnerAddresses', [
        'foreignKey' => 'partner_code'
    ]);
}

Trading Partner Addresses Table

public function initialize(array $config) {
    $this->entityClass('App\Model\Entity\TradingPartnerAddress');
    $this->belongsTo('TradingPartners', [
        'foreignKey' => 'partner_code'
    ]);
}

debug($patchedEtentites);

(int) 0 => object(App\Model\Entity\TradingPartner) {

    .....

    'trading_partner_addresses' => [],
    '[new]' => false,
    '[accessible]' => [
        '*' => true
    ],
    '[dirty]' => [
        'trading_partner_addresses' => true
    ],
    '[original]' => [],
    '[virtual]' => [],
    '[errors]' => [],
    '[repository]' => 'TradingPartners'

Any Ideas why the trading_partner_addresses is being flagged as dirty when it's actually clean?

1

There are 1 answers

0
GuillaumeL On BEST ANSWER

When u patch an entity with some data it's automatically flagged as dirty

$tradingPartners->patchEntities($currentTradingPartners, $partners);

It means you are updating $currentTradingPartners with $partners data so $currentTradingPartners is modified and marked to dirty.

If u want the original data u can use getOriginal method on your entiy's properties, u can also remove the dirty flag with the clean method.

If u got problem to patch entities with associations u must pass an array of options in patchEntity:

$article = $articles->get(1);
$articles->patchEntity($article, $this->request->data(), [
  'associated' => ['Tags', 'Comments.Users']
]);