NCMBとMONACAを使ってアプリ開発（グループごとにログイン情報が見れるようにする）

# 今回したいこと
- 特定のグループがある
- グループごとに見れるデータを分ける
- 他のグループのデータは見れない
- グループに所属させるのは、すでにログインしているユーザーが他のユーザーに許可を与える

# アクセス許可についてまとめる
- NCMBのroleクラスを利用する
- roleクラスの「belongUser」カラムに、ユーザーを所属させる
- 所属させたrole名を、表示絞りたいクラスの「レコード」の「ACL」に付与する。すると、「role」に所属していないと表示されなくなる

つまり、グルーピング用の「role」を作成させ、データ作成時にはその「role」を「レコード」の「ACL」にsetしてあげればいい。
グループに人を入れたいときは、グループに所属している人が入れてあげればいい。
※そのために、ユーザー作成時にはACLを全許可にする必要がある。

それっぽい図：
![Role周りの話.png](https://qiita-image-store.s3.amazonaws.com/0/124604/df8bbeec-a620-8a76-9f8f-3018371c748c.png)


# 作ってみる
## 1.グループを作る
まず第一に以下のソースでグループを作れるようにする。

```javascript:roleを作ってグループにする
function makeRoleTest(){
    var makeNewRole = new ncmb.Role($('#rolenametest').val());
    makeNewRole.save()
                .then(function(){
                    alert("success new role :" + $('#rolenametest').val())
                })
                .catch(function(err){
                    alert("err makeRoleTest")
                });
}
```

## 2.グループに所属させる
ここでは「ログインユーザー」を所属させている。けど、本当はここで、[ncmb.User.getCurrentUser();]の部分で、所属させたいユーザー情報をUserから取得して渡すことがいい。

```javascript:グループに所属させる
//userをroleに所属させる
function belongUserForRoleTest(){
    //ログインユーザーをuserオブジェクトに入れる
    var user = ncmb.User.getCurrentUser();
    //既存のロールを検索
    ncmb.Role.equalTo("roleName",$('#rolenametest').val())
             .fetch()
             .then(function (role){
                if (JSON.stringify(role) === "{}") {
                    alert("err no fetch rolename")
                } else {
                    //会員をロールに追加
                    role.addUser(user).update()
                                      .then(function (role){
                                          alert("Success!! add user:" + user.get("userName") + " for role:" + $('#rolenametest').val())
                                      }).catch(function(err) {
                                          alert("error add user for role")
                    });
                }
            }).catch(function (err){
                alert("please input rolename or login")
            });
}
```

## 3.現在存在しているデータに特定のroleアクセス権限を付与する
この例ではすでに登録しているレコードを呼び出してaclを付与しているが、本当はInsert時点（saveメソッドを使ってデータを渡すとき）にaclをsetしてあげることになる。

```javascript:レコードに特定のroleACLを付与する
//権限を付与する
function addRoleForRecordTest(){
    //aclの状態をどういった形で登録したいかを定義する
    var acl = new ncmb.Acl();
    acl.setRoleReadAccess($('#rolenametest').val(), true) // 入力したロールの読み込みを許可
       .setRoleWriteAccess($('#rolenametest').val(), true) // 入力したロールの書き込みを許可
    //alert(JSON.stringify(acl));
    
    //setしたいレコードを読み出す
    var testData = ncmb.DataStore("testData");
    testData.fetchAll()
        .then(function(results){
            // テストなんで１個めのデータに付与する。一致するデータが１つのみだと、やりやすい
            var getTestData = results[0];
            // 読み出したレコードに新しくaclを設定する
            getTestData.set("acl", acl);
            //alert(JSON.stringify(getTestData));
            getTestData.update();
            alert("success acl update");
        })
        .catch(function(err){
            alert("Error:no data testdata can't fetch");
        });    
}

```

# まとめ
これを応用したら、グループごとに管理をユーザーだけでできるようになるはず。あとは、操作ミスした場合や、所属をやめたいとき用に、RoleクラスのbelongUserカラムからの削除（remove）をできるようにしてあげえばOK！！

# memo
- role自体もレコードなので、ACL次第で見れる見れないが決まる。けどこっちはACLではなくてFetchのときにequalToでもいいかも。うーん。ACLのほうが安全かな。そうすると、作成時とbelongUser時にACLもセットしていく必要があってちょっとめんどい。


- はまったこと
acl.setPublicReadAccess(false) // 全体の読み込みを拒否
→これをするとなぜかうまくいかない。というか、aclにfalseを与える動作がうまくいかない。なぜだろうか。まあけど、特定のroleにのみtrueを入れるように上書くので、falseを使わないで上書けばいいだけなのでいいや。


#参考URL
公式のHPくらいしか参考になるのがなくて切なかった。
http://mb.cloud.nifty.com/assets/sdk_doc/javascript/jsdoc/files/lib_datastore.js.html#l9
http://mb.cloud.nifty.com/assets/sdk_doc/javascript/jsdoc/files/lib_acl.js.html#l5
http://mb.cloud.nifty.com/doc/current/datastore/contents_javascript.html
http://mb.cloud.nifty.com/doc/current/user/manage_privileges_javascript.html