Сохранение данных с использованием AJAX и CakePHP

Я провел сегодня исследование того, как сохранять данные с помощью ajax-запроса в cakephp и теперь есть где, документация на веб-сайте cakephp кажется немного недостающей для этой конкретной темы.

У меня есть несколько сортируемых списков, и мне нужно сохранить позицию каждого элемента списка, если он отсортирован. У меня есть запрос ajax, настроенный следующим образом, который запускается при перемещении элемента:

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

а ссылочная функция в контроллере:

function save_column_order(){
    if($this->RequestHandler->isAjax()){

             SAVE STUFF...

        }
  }

У меня есть помощники и т.д. setup:

var $helpers = array('Html','Form','Js');
var $components = array('Session','Email','RequestHandler');

И его не работает...

Итак, мои вопросы:

1) Каков текущий url для отправки ajax-запроса на действие в контроллере? Это просто/контроллер/действие?

2) Что еще мне нужно сделать с контроллером для доступа к данным ajax?

БОНУС:

3) Есть ли способ включить настраиваемый php файл в фреймворк CakePHP, который ссылается на параметры базы данных, чтобы я мог вручную обновить базу данных mysql?

Ответ 1

Вы были очень близки.

1.) URL-адрес просто/контроллер/действие. Данные передаются в $this- > data и магически доступны в действии. ** Поскольку вы указываете "Js" в своих помощниках вместо "Javascript", я предполагаю, что вы используете Cake 1.3.x и jQuery, потому что jQuery по умолчанию с Cake 1.3 и Js заменяет Javascript/Ajax.

- Исправьте своих помощников:

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

- Исправьте jQuery:

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

2.) Используйте магию торта:

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

- Поскольку вы делаете ajax, вы, вероятно, НЕ хотите, чтобы поведение Cake по умолчанию отображало рендеринг (просто догадка). Если вы хотите вообще визуализировать любой вид, это, вероятно, всего лишь фрагмент разметки для обратного вызова ajax, поэтому вы, вероятно, захотите разместить его в элементе, а не в полноэкранном режиме:

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'); 
}

- В противном случае просто подавите рендеринг:

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

- Если ваше сохранение не работает, убедитесь, что структура $this- > данных Cake-save-friendly. Если вам нужно просмотреть содержимое данных $this- > , встроенная отладка Cake (из любого места вашего приложения) поможет вам выпрямиться:

debug($this->data);

3.) Подождите, что?

Не уверен, что я правильно понимаю, что вы спрашиваете, поэтому, если это не касается вашего вопроса, пожалуйста, уточните, что вы пытаетесь сделать?

Если вы имеете в виду, то Cake позволит вам вручную обновлять записи в таблице/с, да? Хотя я не уверен, зачем вам это нужно. Торт чрезвычайно мощный встроенный ORM - это половина точки фреймворка, а его чрезвычайно всеобъемлющая магия - другая половина.

Вы можете писать строчный SQL с помощью метода Model:: sql(), хотя это не рекомендуется для OOP или многоразового использования.

Когда вы определяете ассоциации в своей модели, вы можете установить для внешнего ключа значение false и указать условия, которые работают как вложенный выбор в автоматическом соединении Cake.

Если вам нужно форсировать join/s, опции Cake $['joins'] дают вам полный контроль; вы можете назначить любой тип JOIN, если LEFT по умолчанию недостаточно хорош для того, что вам нужно сделать.

Вы можете создавать и разбивать привязки модели "на лету" с помощью $this- > Model- > bind()/unbind(). Вы можете указать уровень рекурсии, применить Containable behavior, указать поля для выбора и все условия.

Если вам нужен подзапрос, и Cake просто не может его правильно исправить, $dbo- > buildStatement() построит ваш оператор SQL, а $dbo- > expression() запустит его:

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'));
    }

- Если вы имеете в виду - Cake позволит вам менять конфигурации баз данных "на лету", да. Тем не менее, это может стать довольно хардкорным, особенно когда магия торта является частью ситуации.

Вы можете добавить несколько конфигураций db в /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'
);
}

- Переключение между ними в вашем контроллере/модели происходит там, где ситуация становится немного интенсивной, в зависимости от сложности вашей ситуации:

// Model::getDataSource()->configKeyName holds whichever db config you're using
if ($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');
}

- Если это то, что вы имели в виду, я могу вставить кусок кода, который я написал пару недель назад, требуя, чтобы я сохранил отправку формы ajax (на 2 этапа завершения формы) до 3 таблиц в 2 базах данных (один из которых обслуживал мой Приложение для тортов, а другое - приложение CodeIgniter), показывающее всю эту причудливую работу в действии, а также некоторые старые старомодные макеты для быстрого и быстрого обновления. (Мне также пришлось генерировать выборочные сообщения электронной почты и, наконец, отключить запрос REST, передающий id/s вновь вставленных записей в приложение CI, чтобы инициировать его обработку.)!

В любом случае, HTH.:)

Ответ 2

  • Да, это просто.
    • Для доступа к данным, которые вы отправили, вы можете получить доступ к данным с помощью $this->data, как обычно.
    • Почему бы вам не использовать такие инструменты, как phpmyadmin?

Ответ 3

 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();
        }
    }
}