Cakephp 2 model beforeSave() not being called

David Mauricio picture David Mauricio · Jul 16, 2012 · Viewed 7.5k times · Source

I can't figure out why this code isn't working. The beforeSave is not being called. It's supposed to fail the save and put some lines in the debug log, but it actually does save OK and no lines are written in the debug log.

<?php
class Link extends AppModel {
    var $name = "Link";
    var $belongsTo = array('Category' => array('className' => 'Category', 'foreignKey' => 'category_id'));

  public function beforeSave(){
        if ($this->data[$this->alias]['id'] == null) {
            $this->log("new record", 'debug');
            $link = $this->find('first',array('conditions' => array('Link.status = 1 AND Link.category_id = '.$this->data[$this->alias]['category_id']), 'order' => array('Link.order DESC') ));
            if (is_null($link)) {
                $this->data[$this->alias]['order'] = 1;
            }else{
                $this->data[$this->alias]['order'] = $link['Link']['order'] + 1;
            }
        }
        else {
            $this->log("old record", 'debug');
        }
        return false;
    }
}   
?>

I am launching a save in the controller like this:

public function add($category_id = null)
    {
        if ($category_id == null) {
            $this->Session->setFlash(__('Category id cant be null'),'default', array('class' => 'error-message'));
            $this->redirect(array('action' => 'index', 'controller' => 'categories'));
        }
        else
        {
            if($this->request->is('post'))
            {
                $this->Link->create();
                $this->Link->set('category_id' => $category_id));
                if($this->Link->save($this->request->data))
                {
                    $this->Session->setFlash(__('The link has been saved'),'default', array('class' => 'success'));
                    $this->redirect(array('action' => 'index/'.$category_id));
                }
                else
                    $this->Session->setFlash(__('The link could not be saved. Please, try again.'),'default', array('class' => 'error-message'));
            }
            $this->set('category_id',$category_id);
        }
    }

Another question in StackOverflow points out that the beforeSave method needs to be declared in the Model. I've also done the same thing with another model.

Answer

tigrang picture tigrang · Jul 17, 2012

Here's some general advice and some comments on your code for an answer:

1) If a model callback or any model method isn't working, make sure the correct model is being used and not the default model (AppModel). Check filename, class name, extension (in your case), and location.

2) You're using conditions array incorrectly (in this case).

array('conditions' => array('Link.status = 1 AND Link.category_id = '.$this->data[$this->alias]['category_id'])

You should really be doing:

array('conditions' => array('Link.status' => 1, 'Link.category_id' => $this->data[$this->alias]['category_id'])

3) Your redirect is being used wrong

$this->redirect(array('action' => 'index/'.$category_id));

Should be:

$this->redirect(array('action' => 'index', $category_id));