2015年4月1日水曜日

kintone@アプリAのINSERT時にレコード番号を取得したい

●背景
アプリAでレコードを登録する際の(app.record.create.submit)では
レコードがまだ作成されていないので「レコード番号」は未採番だ。
番号の予約も出来ていないので何番になるか分からない。

だがアプリAのINSERT時に、アプリBにも同時にINSERTしたい場面はあるだろう。
そしてアプリBには「アプリAのレコード番号」をカラムとして持っておき、
両データを関連付けたい、そんな場合、どうすれば良いかを考えた。

●解決策1
アプリAの最終レコード番号+1を自レコード番号とする方式
 →よく目にする、一見して無駄のない処理方式である、
  が、正常な挙動が望めない場合がある。
  例えば「作成者がログインユーザのレコードのみ閲覧可能」のような、
  ユーザに対してレコードの閲覧権限をいじっている場合がそうだ。

  「JavaScriptでの閲覧権限」は「ログインユーザ」と同じレベルのため、
  最終番号を保持したレコードが当該ログインユーザではない場合、
  IDが参照できず、重複してしまう。

  これ以外にも例えばアプリ操作者が複数いる場合、
  ユーザ1が最新レコードを参照してる間に
  ユーザ2も同じレコードを参照してしまい、
  それぞれが+1した同じレコード番号を登録してしまう可能性がある。

  上述の心配がまったくいらない業務では、以下のソースを使えば良い
●サンプルコード1
/***************************************************************************************************
* 最新レコード番号を取得する1
* @param event イベント
* @param appID 取得対象のアプリID
* @return recID 現レコード番号の最大値+1。レコード非存在時は1。処理失敗時は-1。
***************************************************************************************************/
function getLastRecID1(event, appID) {
    // 戻り値の設定(処理失敗時は-1)
    var recID = -1;

    // URLを設定する
    var appUrl = kintone.api.url('/k/v1/records', true)
        + '?app=' + appID
        + '&query=' + encodeURI('order by レコード番号 desc limit 1');

    // 最新レコード番号を取得
    try {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open("GET", appUrl, false);
        xmlHttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
        xmlHttp.send(null);
        if (xmlHttp.status == 200 && window.JSON) {
            var obj = JSON.parse(xmlHttp.responseText);
            if (obj.records[0] != null) {
                // recID = 現レコード番号の最大値+1
                recID = parseInt(obj.records[0][' id']['value']) + 1;
            } else {
                // recID = 1(レコード非存在時)
                recID = 1;
            }
        }
    } catch (e) {
    }
    return recID;
}
●解決策2
・アプリCを作り、アプリAの新規登録時、まずアプリCにINSERTを行う。
 INSERTしたレスポンスで取得できるIDをアプリAのレコード番号として使う方式。
 →アプリCというアプリを作る必要があり、
  無駄な採番が行われてしまいやすい等の欠点はあるが、
  レコード番号の予約をほぼ完ぺきな形で行うことができる。
●サンプルコード2
/***************************************************************************************************
* 最新レコード番号を取得する2
* @param event イベント
* @param appID_RecIDManager レコードID採番用アプリ(アプリC)のAppID
* @return recID 予約した最新レコード番号。処理失敗時は-1。
***************************************************************************************************/
function getLastRecID2(event, appID_RecIDManager) {
    // 戻り値の設定(処理失敗時は-1)
    var lastRecID = -1;

    /*=========================================
     * 「RecIDManager(アプリC)」に登録
     =========================================*/
    var param =
    {
        "app": appID_RecIDManager,
        "record": {}
    }
    // CSRFトークンの取得
    var token = kintone.getRequestToken();
    param["__REQUEST_TOKEN__"] = token;
    // 同期リクエストを行う
    var appUrl = kintone.api.url('/k/v1/record');
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open('POST', appUrl, false);
    xmlHttp.setRequestHeader('Content-Type', 'application/json');
    xmlHttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    xmlHttp.send(JSON.stringify(param));
    if (xmlHttp.status == 200 && window.JSON) {
        var respdata = JSON.parse(xmlHttp.responseText);
        lastRecID = respdata["id"];
    }
    return lastRecID;
}

0 件のコメント:

コメントを投稿