cakePHP2インストール
cakephp-2.8.4をgitでworkspaceにDLする。
$ cd workspace $ git clone -b 2.x git://github.com/cakephp/cakephp.git $ chmod 0777 -R ./cakephp/app/tmp/
今回apacheの公開ディレクトリが workspace/htdocs/なので以下の設定が必要。
$ mv ./cakephp/app/webroot ./htdocs
/cakephp/app/webroot/index.php
...
if (!defined('ROOT')) {
//define('ROOT', dirname(dirname(dirname(__FILE__))));
// ↓以下に変更↓
define('ROOT', dirname(dirname(__FILE__)) . DS . 'cakephp');
}
...
if (!defined('APP_DIR')) {
//define('APP_DIR', basename(dirname(dirname(__FILE__))));
// ↓以下に変更↓
define('APP_DIR', 'app');
}
...
SQLite3の設定
ここでは記事マスタ(mas_entries)とカテゴリ(met_categories)という2つのテーブルを想定する。
それぞれ主キー(entry_id, category_id)と登録日時(created), 更新日時(modified), 論理削除日時(deleted)をもつ。
$ cd workspace $ mkdir sqlite3 $ vi sqlite3/create-table.sql
create-table.sql
CREATE TABLE `mas_entries` (
`entry_id` INTEGER PRIMARY KEY AUTOINCREMENT,
`created` datetime NULL,
`modified` datetime NULL,
`deleted` datetime NULL,
`title` VARCHAR(50),
`content` VARCHAR(1000),
`category_id` INTEGER
);
CREATE TABLE `met_categories` (
`category_id` INTEGER PRIMARY KEY AUTOINCREMENT,
`created` datetime NULL,
`modified` datetime NULL,
`deleted` datetime NULL,
`name` VARCHAR(50),
`display_order` INTEGER
);
BEGIN TRANSACTION;
INSERT INTO `met_categories` (`created`, `modified`, `name`, `display_order`) VALUES(datetime('now', 'localtime'), datetime('now', 'localtime'), 'ニュース', 1);
INSERT INTO `met_categories` (`created`, `modified`, `name`, `display_order`) VALUES(datetime('now', 'localtime'), datetime('now', 'localtime'), '商品情報', 2);
INSERT INTO `met_categories` (`created`, `modified`, `name`, `display_order`) VALUES(datetime('now', 'localtime'), datetime('now', 'localtime'), 'IR情報', 3);
COMMIT;
$ sqlite3 sqlite3/rest-test.sqlite3 < sqlite3/create-tables.sql $ chmod 0777 sqlite3 $ chmod 0666 sqlite3/rest-test.sqlite3 $ mv cakephp/app/Config/database.php.default cakephp/app/Config/database.php $ vi cakephp/app/Config/database.php
cakephp/app/Config/database.php DBの設定を以下のように変更。
... public $default = array( 'datasource' => 'Database/Sqlite', 'persistent' => false, 'database' => '/home/test/workspace/sqlite3/rest-test.sqlite3', 'prefix' => '', 'encoding' => 'utf8', ); ...
RESTの設定
cakephp/app/Config/routes.php の require CAKE . 'Config' . DS . 'routes.php'; より前にRESTの設定を記述する。
/**
* REST config
*/
Router::mapResources('entries');
Router::mapResources('categories');
Router::parseExtensions();
cakephp/app/Model にモデルファイル追加。
cakephp/app/Model/Entry.php
<?php
class Entry extends AppModel {
/**
* モデル名
*/
public $name = 'Entry';
/**
* 使用テーブル
*/
public $useTable = 'mas_entries';
/**
* 主キー
*/
public $primaryKey = 'entry_id';
/**
* list取得時表示フィールド
*/
public $displayField = 'title';
/**
* リレーション
*/
public $belongsTo = [
'Category' => [
'className' => 'Category',
'foreignKey' => 'category_id',
],
];
}
cakephp/app/Model/Category.php
<?php
class Category extends AppModel {
/**
* モデル名
*/
public $name = 'Category';
/**
* 使用テーブル
*/
public $useTable = 'met_categories';
/**
* 主キー
*/
public $primaryKey = 'category_id';
/**
* list取得時表示フィールド
*/
public $displayField = 'name';
}
cakephp/app/Controller にコントローラファイル追加。
cakephp/app/Controller/RestController.php
<?php
class RestController extends AppController {
/**
* コンポーネント
*/
public $components = ['RequestHandler'];
/**
* メインモデル
*/
public $mainModel;
/**
* 一覧表示
*/
public function index() {
$mainModel = $this->mainModel;
$all = $this->$mainModel->find('all');
$this->set([
'all' => $all,
'_serialize' => ['all']
]);
}
/**
* 詳細表示
*/
public function view($id) {
$mainModel = $this->mainModel;
$conditions = [
[$this->$mainModel->name . '.' . $this->$mainModel->primaryKey => $id]
];
$first = $this->$mainModel->find('first', compact('conditions'));
$this->set([
'first' => $first,
'_serialize' => ['first']
]);
}
/**
* 登録
*/
public function add() {
$mainModel = $this->mainModel;
$this->$mainModel->create();
if ($this->$mainModel->save($this->request->data)) {
$message = 'Saved';
} else {
$message = 'Error';
}
$this->set([
'message' => $message,
'_serialize' => ['message']
]);
}
/**
* 更新
*/
public function edit($id) {
$mainModel = $this->mainModel;
$this->$mainModel->id = $id;
if ($this->$mainModel->save($this->request->data)) {
$message = 'Saved';
} else {
$message = 'Error';
}
$this->set([
'message' => $message,
'_serialize' => ['message']
]);
}
/**
* 論理削除
*/
public function delete($id) {
$mainModel = $this->mainModel;
$conditions = [
[$this->$mainModel->name . '.' . $this->$mainModel->primaryKey => $id]
];
$message = 'Error';
if ($first = $this->$mainModel->find('first', compact('conditions'))) {
$first[$this->$mainModel->name]['deleted'] = date("Y-m-d H:i:s");
if ($this->$mainModel->save($first)) {
$message = 'Deleted';
}
}
$this->set([
'message' => $message,
'_serialize' => ['message']
]);
}
}
cakephp/app/Controller/EntriesController.php
<?php
App::uses('RestController', 'Controller');
class EntriesController extends RestController {
/**
* 使用モデル
*/
public $uses = ['Entry'];
/**
* メインモデル
*/
public $mainModel = 'Entry';
}
cakephp/app/Controller/CategoriesController.php
<?php
App::uses('RestController', 'Controller');
class CategoriesController extends RestController {
/**
* 使用モデル
*/
public $uses = ['Category'];
/**
* メインモデル
*/
public $mainModel = 'Category';
}
Backboneのインストール
workspace/htdocs/js/lib/ を作成し,
・backbone-min.js
・jquery.min.js
・require.js
・text.js
・underscore-min.js
を設置。それぞれのファイルはWEB上から取得。
workspace/htdocs/app を作成し,以下のディレクトリ構造を作成する。
app/
├ Collection/
├ Config/
├ Model/
├ Template/
└ View/
次に設定ファイルを作成。
workspace/htdocs/app/Config/require_config.js
var require = {
baseUrl: '/app/',
paths: {
'jquery': '/js/lib/jquery.min',
'underscore': '/js/lib/underscore-min',
'backbone': '/js/lib/backbone-min',
'text': '/js/lib/text',
},
shim: {
'backbone': {
deps: ['jquery', 'underscore'],
exports: 'Backbone'
},
'text': {
deps: ['backbone'],
exports: 'Text'
}
}
};
メインスクリプトを設置。
workspace/htdocs/app/main.js
define(function(require){
// ライブラリ
var $ = require('jquery');
var _ = require('underscore');
var Backbone = require('backbone');
});
htmlファイルを設置。
workspace/htdocs/entries.html
最低限のインストールは終了。
BackboneのModel,Collectionの作成
workspace/htdocs/app/Model/AppModel.js
define(function(require){
var Backbone = require('backbone');
return Backbone.Model.extend({
/**
* URL
*/
url: function() {
if (this.id) {
return this.urlRoot + '/' + this.id + '.json';
} else {
return this.urlRoot + '.json';
}
},
/**
* parse
*/
parse: function(response) {
var data = response;
if (typeof(data.first) !== 'undefined') {
for (var i in data.first) {
data[i] = data.first[i];
}
delete(data.first);
}
if (typeof(data[this.name]) !== 'undefined') {
for (var i in data[this.name]) {
data[i] = data[this.name][i];
}
delete(data[this.name]);
}
return data;
}
});
});
workspace/htdocs/app/Model/Entry.js
define(function(require){
var Backbone = require('backbone');
var AppModel = require('Model/AppModel');
return AppModel.extend({
/**
* モデル名
*/
name: 'Entry',
/**
* URL ROOT
*/
urlRoot : '/entries',
/**
* idAttribute
*/
idAttribute: 'entry_id'
});
});
workspace/htdocs/app/Model/Category.js
define(function(require){
var Backbone = require('backbone');
var AppModel = require('Model/AppModel');
return AppModel.extend({
/**
* モデル名
*/
name: 'Category',
/**
* URL ROOT
*/
urlRoot : '/categories',
/**
* idAttribute
*/
idAttribute: 'category_id'
});
});
workspace/htdocs/app/Collection/AppCollection.js
define(function(require){
var Backbone = require('backbone');
return Backbone.Collection.extend({
/**
* parse
*/
parse: function(response) {
if (typeof(response.all) !== 'undefined') {
return response.all;
} else {
return response;
}
}
});
});
workspace/htdocs/app/Collection/Entries.js
define(function(require){
var Backbone = require('backbone');
var AppCollection = require('Collection/AppCollection');
var Entry = require('Model/Entry');
return AppCollection.extend({
/**
* コレクション名
*/
name: 'Entries',
/**
* モデル
*/
model: Entry,
/**
* URL
*/
url: '/entries.json'
});
});
workspace/htdocs/app/Collection/Categories.js
define(function(require){
var Backbone = require('backbone');
var AppCollection = require('Collection/AppCollection');
var Category = require('Model/Category');
return AppCollection.extend({
/**
* コレクション名
*/
name: 'Categories',
/**
* モデル
*/
model: Category,
/**
* URL
*/
url: '/categories.json'
});
});
準備完了。
BackboneでRESTテスト
先ほど作ったworkspace/htdocs/app/main.jsを修正しながらテスト
1. 一覧取得テスト
var Categories = require('Collection/Categories');
var categories = new Categories();
categories.fetch({
success: function(categories) {
console.log(categories);
}
});
2. 登録テスト
var Entry = require('Model/Entry');
var entry = new Entry();
entry.set({
title: 'ニューステスト',
content: 'これは初めての投稿です。',
category_id: 1
});
entry.save();
3. 1件取得テスト
var Entry = require('Model/Entry');
var entry = new Entry();
entry.id = 1;
entry.fetch({
success: function() {
console.log(entry);
}
});
4. 更新テスト
var Entry = require('Model/Entry');
var entry = new Entry();
entry.set({
entry_id: 1,
title: 'これは書き換えテスト'
});
entry.save();
5. 削除テスト
var Entry = require('Model/Entry');
var entry = new Entry();
entry.id = 1;
entry.fetch({success: function(){
entry.destroy();
}});

