4

I have a beforeSave-callback which is called just fine whenever I create a new entity. However when I am editing, it's not called at all. Could not find anything in the documentation that could be helpful.

Here's my edit function:

public function edit($id = null) {
    if (!$id) {
        throw new NotFoundException(__('Invalid article'));
    }

    $article = $this->Articles->get($id);
    if ($this->request->is(['post', 'put'])) {
        $this->Articles->patchEntity($article, $this->request->data);
        if ($this->Articles->save($article)) {
            $this->Flash->success(__('Your article has been updated.'));
            return $this->redirect(['action' => 'index']);
        }
        $this->Flash->error(__('Unable to update your article.'));
    }

    $this->set('article', $article);
} 
Bob
  • 873
  • 1
  • 8
  • 21
yBrodsky
  • 4,981
  • 3
  • 20
  • 31
  • Are you sure that your save operation does make it that far in the first place? ie, is it succesfull? Because if it is, then I would kinda doubt that the event is not being dispatched, as this happens in one and the same method for insert as well as updates. – ndm Apr 16 '15 at 07:39
  • Please post the code of your `beforeSave`-callback too. – Bob Apr 16 '15 at 14:18
  • I am sure cause the record is modified. Inside my beforeSave I am simply calling a die(), so there's not way it's calling it without me noticing. – yBrodsky Apr 16 '15 at 20:41
  • Well, if the record is being saved, then the event is being dispatched, unless the dispatcher is broken. Check whether the `$this->Articles` instance is really an instance of your actual table class (`debug(get_class($this->Articles))`) that has the callback method implemented, and not an "auto-table" (instance of `Cake\ORM\Table`), also make sure that you're not messing with [**`Table::implementedEvents()`**](https://github.com/cakephp/cakephp/blob/3.0.1/src/ORM/Table.php#L2202). – ndm Apr 17 '15 at 13:53
  • Will check later tonight and get back at you. Thanks for the help. – yBrodsky Apr 17 '15 at 16:09
  • @ndm $this->Articles is instance of 'App\Model\Table\ArticlesTable'. Seems ok to me. I didn't touch the Table's implementedEvents. – yBrodsky Apr 17 '15 at 23:50
  • Well, then I'm stumped. You'll have to do some further debugging on your own, hack your way into the core to check where in the save operation things are going wrong. – ndm Apr 18 '15 at 00:19

4 Answers4

14

The beforeSave function will be triggered only if the data you post/edit is modified.

//triggers only if an entity has been modified
public function beforeSave(Event $event, Entity $entity)
{
    if($entity->isNew()) {       
        //on create
    } else {
        //on update
    }
}
eM.
  • 165
  • 1
  • 8
1

I also had the problem that the tutorial got stuck on this point, but I used the bin/cake bake command to autogenerate the ArticlesTable code and it added this validator:

$validator
        ->scalar('slug')
        ->maxLength('slug', 191)
        /*->requirePresence('slug', 'create')*/
        ->notEmptyString('slug')
        ->add('slug', 'unique', ['rule' => 'validateUnique', 'provider' => 'table']);

When I commented the requirePresence() it solved this issue for me. If you have requirePresence('fieldName', 'create') for validation, you will get an error if you don't have that field on a post when creating the new Article entity.

Navguls
  • 11
  • 1
0

Yes, your need use Event and Entity object:

check this example:

// src/Model/Table/ArticlesTable.php

use Cake\Event\Event;
use Cake\ORM\Entity;

public function beforeSave(Event $event, Entity $entity) {
    if ($entity->isNew()) {
        return true;
    }
    // edit code
}
fitorec
  • 4,257
  • 2
  • 24
  • 18
0

Another way to write the same code:

public function beforeSave(\Cake\Event\Event $event, \Cake\ORM\Entity $entity, \ArrayObject $options){

    if($entity->isNew()) {
        // on create
    } else {
        // on update
    } 
}
abiratsis
  • 7,051
  • 3
  • 28
  • 46