Save data using AJAX and CakePHP Save data using AJAX and CakePHP ajax ajax

Save data using AJAX and CakePHP


You were very close.

1.) URL is simply /controller/action. Data is passed in $this->data and is magically available in the action.**Since you list 'Js' in your helpers instead of 'Javascript', I'm presuming you're using Cake 1.3.x and jQuery, because jQuery is the default with Cake 1.3 and Js replaced Javascript / Ajax.

-- Fix your helpers:

var $helpers = array('Html', 'Form', 'Js'=>array("Jquery"));

-- Fix your jQuery:

$.ajax({    url:'/orders/save_column_order',    type:'POST',    data:data});

2.) Use Cake's magic:

function save_column_order() {    if ($this->data != null) {        $this->Model->save($this->data);    // whatever else needs doing...    }}

-- Since you're doing ajax, you probably do NOT want Cake's default view-rendering behavior (just a guess.) If you want to render any view at all, it's probably just a snip of markup for an ajax callback, so you probably want to place it in an element rather than a full-blown view:

function save_column_order() {    // ...    /* arg 1 - you can specify any view or element you like.        arg 2 - enforces your preferred request handling and layout */    $this->set(compact('vars', 'for', 'view'));    $this->render('/elements/new_column_order', 'ajax'); }

-- Otherwise, just suppress rendering:

function save_column_order() {    ...         $this->autoRender = false;}

-- If your save isn't working, make sure the structure of $this->data is Cake-save-friendly. If you need to view the contents of $this->data, Cake's built-in debugging (from anywhere in your app) will help you get straightened out:

debug($this->data);

3.) Wait, what?

Not sure I understand what you're asking correctly, so if this does not cover your question, please clarify what you're trying to do?

If you mean, will Cake allow you to manually update records in a table/s, yes? Although I'm not sure why you would want to. Cake's extremely powerful built-in ORM is half the point of the framework, and its extremely comprehensive magic is the other half.

You can scribble off straight SQL with the Model::sql() method, although this is discouraged it's not very OOP or reusable.

When you define associations in your model, you can set the foreign key to false and specify conditions that work like a nested select in Cake's auto joins.

If you need to force join/s, Cake's $options['joins'] give you completely granular control; you can designate any type of JOIN if the default LEFT isn't good enough for what you need to do.

You can make and break model bindings on the fly with $this->Model->bind() / unbind(). You can specify the level of recursion, apply Containable behavior, specify the fields to select and all conditions.

If you need a subquery and Cake just can't get it right, $dbo->buildStatement() will construct your SQL statement and $dbo->expression() will fire it:

function intricate() {    $dbo = $this->Rate->Status->getDataSource();    $subquery = $dbo->buildStatement(        array(            'fields' => array('`Status`.`id`'),            'table' => $dbo->fullTableName($this->Rate->Status),            'alias' => 'Status',            'limit' => null,            'offset' => null,            'joins' => array(),            'conditions' => $subqueryConditions,            'order' => null,            'group' => null            ),        $this->Rate->Status        );    $subquery = "Status.id = (".$subquery.")";    $status = $dbo->expression($subquery);    $options['fields']=        array(            "Rate.id", "Rate.plan_id", "Rate.status_id","Rate.rate", "Plan.id",             "Plan.company_id", "Plan.name", "Company.id", "Company.name"        );    $options['conditions']=        array(            $status,             "Geographical.name LIKE '%{$this->zip}%'"        );    $rates = $this->Rate->find('all', $options);    $this->set(compact('rates'));    }

-- If you mean - will Cake allow you to swap out database configurations on the fly, yes. However, doing so can get pretty hardcore, especially when Cake's magic is part of the situation.

You can add multiple db configs in /app/config/database.php -

class DATABASE_CONFIG {    var $default = array(        'driver' => 'mysql',        'persistent' => false,        'host'=>'localhost',        'login' => 'cake',    'password' => 'icing',        'database' => 'dev');    var $offsite = array(        'driver' => 'mysql',        'persistent' => false,        'host' => '11.22.33.44', // or whatever        'login' => 'cake',        'password' => 'frosting',        'database' => 'live');}

-- Switching between them in your controller / model is where things get a little intense, depending on the complexity of your situation:

// Model::getDataSource()->configKeyName holds whichever db config you're usingif ($this->Model->getDataSource()->configKeyName != 'default') {    // do something, for example, change models, tables, reload schema, etc.    $this->loadModel('Special')    $this->Model->table = 'extras';    $this->Model->schema(true);} else {    // predictably, Model::setDataSource($configKey) changes configs    $this->Model->setDataSource('offsite');}

-- If this is what you meant, I can paste a chunk of code I wrote a couple weeks ago requiring I save an ajax form submission (at 2 stages of form completion) to 3 tables in 2 databases (one serving my Cake application, the other serving a legacy CodeIgniter application) showing all this fancy footwork in action along with some good old-fashioned Cake magic join-through save/update shortcuts. (I also had to generate selective emails and finally, fire off a REST request passing the id/s of the newly inserted records to the CI application to trigger it's processing. Whew!)

Anyway, HTH. :)


  1. Yes, it's simple as that.
    1. To access the data like you sent it you can access the data with $this->data as usual
    2. Why don't you use tools like phpmyadmin?


 public function add_project() {    $this->autoRender = false;    $this->layout = 'ajax';    if ($this->RequestHandler->isAjax()) {        $this->Project->set($this->request->data);        $this->request->data['Project']['user_id'] = $this->Session->read('Auth.User.id');        $this->request->data['Project']['created_by'] = $this->Session->read('Auth.User.id');        $this->request->data['Project']['updated_by'] = $this->Session->read('Auth.User.id');        //$this->request->data['Skill']['accept_decline'] = 0;        $this->User->set($this->request->data['Project']);        Configure::write('debug', 0);        if ($this->Project->validates(array('fieldList' => array('project_title', 'show_on', 'summary')))) {            if ($this->Project->save($this->request->data, false)) {                $response['status'] = 'succses';                $response['message'] = 'data  sent';                echo json_encode($response);                exit();            } else {                $response['status'] = 'error';                $response['model'] = 'Project';                $response['message'] = 'data not sent';                echo json_encode($response);                exit();            }        } else {            $response['status'] = 'invalid';            $response['model'] = 'Project';            $errors = $this->Project->validationErrors;            $response['errors'] = $errors;            echo json_encode($response);            exit();        }    }}