バックボーンJSモデルの使い方メモ

Railsとバックボーンが非常に相性がよく、簡単にREST APIを使ったデータ連携を作成できます。
こちらの[記事](http://qiita.com/opengl-8080/items/36e9b380c64ba7766511)が参考になるのでぜひ参照してみましょう。

バックボーンとRailsでREST APIを使ったデータ連携

#  1. バックエンド
Railsでは何もしなくてもRESTful APIをサポートしてるので設定は下記のみ

### ルーター一覧
| アイテム名 | 値段 |
| ------------ | ------------- |
| GET /api/v1/profile | profile#index |
| POST /api/v1/profile | profile#create |
| GET /api/v1/profile/new | profile#new |
| GET /api/v1/profile/:id/edit | profile#edit |
| GET /api/v1/profile/:id | profile#show |
| PATCH /api/v1/profile/:id | profile#update |
| PUT /api/v1/profile/:id | profile#update |
| DELETE /api/v1/profile/:id | profile#destroy |

### routes.rb
```ruby
Rails.application.routes.draw do
.....
      # テスト ユーザープロフィール処理用のコントローラ
      resources :profile
.....
```
### profile_controller.rb
```ruby
class ProfileController < ApplicationController
  protect_from_forgery except: :update

  # GET /api/v1/profile .... collection.fetch();
  def index
      render status: 200, json: { status: 'fetch', user: [User.last,User.first], rank: 1, test:true }
  end
  # PUT /api/v1/profile .... collection.create();
  def create
    render status: 200, json: { status: 'save' }
  end
  # GET /api/v1/profile/:id ... model.fetch();
  def show
    render status: 200, json: { status: 'fetch', user: User.last }
  end
  # PUT /api/v1/profile/:id ... model.save();
  def update
    render status: 200, json: { status: 'fetch', user: User.last }
  end

end
```


# 2. フロントエンド
## 2.1 URLの定義
```javascript
var targetURL = '/api/v1/profile';
```
##  2.2 モデルの生成
```javascript
// モデル
//  Model Profile を作成
var ModelPofile = Backbone.Model.extend({urlRoot :targetURL});
var model = new ModelPofile({id: 123});
```
##  2.3 モデルの値変更監視
```javascript
//  値変更時のイベントハンドラ設定
model.on("change:status", function(model, status) {
  console.log("Changed status from " + model.previous("status") + " to " + status);
});
//  ユーザーステータスの変更を取得
model.on("change:user", function(model, user) {
  console.log("Changed status from " + JSON.stringify(model.previous("user")) + " to " + JSON.stringify(user));
});
```
##  2.4 データ取得と保存
```javascript
//  モデルをfetch
model.fetch({
  success : function success(collection, res, options) {
    console.log('succeed to receive data');
    //  モデルの内容を編集してみる
    collection["attributes"]["status"] = 'change';
    collection["attributes"]['user']["nickname"] = 'kumac';
    console.log(collection);

    //  モデルを保存
    model.save({
      success : function(model, resp) {
        console.log(resp);
      },
      error : function(model, resp) {
        return false;
      }
    });
  },
  error : function error() {
    // 通信失敗時の処理
  }
});
```
##  2.5 コレクションの作成と複雑なJSONを扱う為のカスタマイズ
```javascript
var CollectionProfile = Backbone.Collection.extend({
    url: targetURL,
    post: true,
    model: ModelPofile,
    status: undefined,
    rank: undefined,
    test: undefined,
    // 複雑な構造のJSONを受け取る場合にParseをカスタマイズ
    parse: function parse(data) {
      this.status = data.status;
      this.rank = data.rank;
      this.test = data.test;
      return data.user;
    }
});
```
##  2.6 コレクションの取得とバルクアップデート
```javascript
//  コレクションをfetch
var model2 = new CollectionProfile();
model2.fetch({
  success : function success(collection, res, options) {
    for(var idx in collection['models']){
      console.log(collection['models'][idx].attributes);
    }
    model2.sync('create', collection, {
      url: targetURL,
      success: function(data){
        console.log('succeed to post');
      },
      error: function(){
        console.log('error');
      }
    });
  },
  error : function error() {
    // 通信失敗時の処理
    console.log();
  }
});

```