アプリ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/***************************************************************************************************
* 最新レコード番号を取得する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;
}
・アプリ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;
}
* 最新レコード番号を取得する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 件のコメント:
コメントを投稿