2016-06-23 5 views
2

更新:私はかなり前進しています。投稿の末尾をご覧ください...Sequelize、NodeJS、AngularJSを使用してn:mの関係を持つレコードを作成する

私はsql-fullstack yeomanジェネレータをベースにしたプロジェクトに取り組んでおり、含まれているサンプルコードを参考にしています。物事はほとんどの部分は、順調に進んでいるが、私は、双方向のnを持つ2つのテーブル/モデルを持っているシナリオで、今だ:Mの関係:

タスクグループ:

module.exports = function(sequelize, DataTypes) { 
    var TaskGroup = sequelize.define("TaskGroup", { 
    taskGroupID: { 
     field: "TaskGroupID", 
     type: DataTypes.INTEGER, 
     allowNull: false, 
     unique: true, 
     autoIncrement: true, 
     primaryKey: true 
    }, 
    name: { 
     field: "Name", 
     type: DataTypes.STRING, 
     allowNull: false 
    }, 
    description: { 
     field: "Description", 
     type: DataTypes.STRING 
    }, 
    modifiedBy: { 
     field: "ModifiedBy", 
     type: DataTypes.STRING 
    } 
    }); 

とタスク:

module.exports = function(sequelize, DataTypes) { 
    var Task = sequelize.define("Task", { 
    taskID: { 
     field: "TaskID", 
     type: DataTypes.INTEGER, 
     allowNull: false, 
     unique: true, 
     autoIncrement: true, 
     primaryKey: true 
    }, 
    name: { 
     field: "Name", 
     type: DataTypes.STRING, 
     allowNull: false 
    }, 
    description: { 
     field: "Description", 
     type: DataTypes.STRING 
    }, 
    isOnRunsheet: { 
     field: "IsOnRunsheet", 
     type: DataTypes.BOOLEAN 
    }, 
    modifiedBy: { 
     field: "ModifiedBy", 
     type: DataTypes.STRING 
    } 
    }); 

関係:クライアント側で

// Tasks can belong to more than one group, and groups can belong to more than one task 
    db['TaskGroup'].belongsToMany(db['Task'], {as: 'Tasks', through: 'TaskGrouping'}); 
    db['Task'].belongsToMany(db['TaskGroup'], {as: 'TaskGroups', through: 'TaskGrouping'}); 

、ユーザーは新しいTAを作成することができます複数の選択リストを使用して関連するタスクグループを指定します。タスクが保存されるとき、私は両方のタスクフィールドと関連付けられたタスクグループの配列を持っています。 A postは、サーバーがタスクレコードを作成できるように、この情報を含む要求本体で作成されます。

残念ながら、私はレコードを作成することはできません。私は多くの繰り返しを経てきましたが、私は合理的な例外であると思われるものを手に入れています - 私はちょうど "合理的な"ことが何であるかについて困惑しています...

例外:

$scope.createTask = function() { 
    if($scope.newTask === '') { 
    return; 
    } 
    $scope.newTask.modifiedBy = 'tkturney'; 
    var taskBundle = { 
     task: $scope.newTask, 
     taskGroups: $scope.selectedGroups 
    }; 
    $http.post('/api/tasks', taskBundle); 
    setTimeout(function() { 
    $scope.currentTask = $scope.newTask; 
    $scope.newTask = ''; 
    $scope.addingTask = false; 
    refreshTasks(); 
    }, 250); 
}; 

...と、サーバー側で:

exports.create = function(req, res) { 
    var task = Task(req).build(req.body.task); 
    task.setTaskGroups(req.body.taskGroups); 
    task 
    .save() 
    .then(function() { 
     return res.status(201).json(task); 
    }) 
    .catch(function (err){ 
     if(err) { return handleError(res, err); } 
    }); 
}; 

Unhandled rejection SequelizeDatabaseError: Cannot insert the value NULL into column 'TaskTaskID', table 'HelpCard 
.dbo.TaskGrouping'; column does not allow nulls. INSERT fails. 
    at Query.formatError (C:\Projects\helpcard2\node_modules\sequelize\lib\dialects\mssql\query.js:215:10) 
    at Request.userCallback (C:\Projects\helpcard2\node_modules\sequelize\lib\dialects\mssql\query.js:66:25) 
    at Request.callback (C:\Projects\node_modules\tedious\lib\request.js:33:27) 
    at Connection.message (C:\Projects\node_modules\tedious\lib\connection.js:1179:27) 
    at Connection.dispatchEvent (C:\Projects\node_modules\tedious\lib\connection.js:519:45) 
    at MessageIO.<anonymous> (C:\Projects\node_modules\tedious\lib\connection.js:439:23) 
    at emitNone (events.js:67:13) 
    at MessageIO.emit (events.js:166:7) 
    at ReadablePacketStream.<anonymous> (C:\Projects\node_modules\tedious\lib\message-io.js:92:15) 
    at emitOne (events.js:77:13) 
... 

ここでは、クライアント側のコードがあります

私は明らかに何かが欠けていると確信していますが、私が見つけたドキュメンテーションは、このようなシナリオでかなり明るいものでした。私はどんな指導にも感謝します。私はちょうど後遺症に陥りつつあり、私は噛むことができる以上に噛んでいるかもしれないと感じています。:)

アップデート:SQLを詳しく見てから、私は発見しましたジョインテーブル(TaskGroupings)に挿入しようとしたときに例外がスローされたことを示します。タスクのプライマリIDにNULLを挿入しようとしましたが、これは一般的には良いことではありません。コードを見ると、レコードを保存する前に関連付けを追加しようとしていて、PKが残っていないことがわかりました。 save()がその問題を処理した後にtask.addTaskGroups()を移動してください。

しかし、実際のIDの代わりに、TaskGroupオブジェクトの配列を 'addTaskGroup() `呼び出しに渡していることもわかりました。

$scope.createTask = function() { 
    if($scope.newTask === '') { 
    return; 
    } 
    $scope.groupKeys = []; 
    angular.forEach($scope.selectedGroups, function(taskGroup) { 
    $scope.groupKeys.push(taskGroup.taskGroupID); 
    }); 
    $scope.newTask.modifiedBy = 'tkturney'; 
    var taskBundle = { 
     task: $scope.newTask, 
     taskGroups: $scope.groupKeys 
    }; 
    $http.post('/api/tasks', taskBundle); 
    ... 

私は、デバッガを見てみると、私はtaskGroupオブジェクトのすべてを見ることができますが、taskGroup.taskGroupIDundefinedとして戻って来ているので、私はまだ取得しています:だから、私はそうのようなクライアント側のコントローラを修正しました私は協会の反対側にPKを渡していないので例外です。

このコードフラグメントに何が起こるかについて何か飛躍していますか?特定の例外が離れて行ったこと

exports.create = function(req, res) { 
    var task = Task(req).build(req.body.task); 
    task 
    .save() 
    .then(function() { 
     task.setTaskGroups(req.body.taskGroups); 
     return res.status(201).json(task); 
    }) 
    .catch(function (err){ 
     if(err) { return handleError(res, err); } 
    }); 
}; 

:これに

exports.create = function(req, res) { 
    var task = Task(req).build(req.body.task); 
    task.setTaskGroups(req.body.taskGroups); 
    task 
    .save() 
    .then(function() { 
     return res.status(201).json(task); 
    }) 
    .catch(function (err){ 
     if(err) { return handleError(res, err); } 
    }); 
}; 

:このからサーバ側のコントローラを変更することにより

答えて

2

[OK]を、。私が欠けていたことは(顔が私を見つめていたにもかかわらず)、2つの別々のインサートが起こっているという事実でした.1つはタスクのため、もう1つは関連のためです。私はタスクを保存する前に関連付けを設定する必要があると考えていましたが、その関連付けによって別の挿入が行われたことを認識しませんでした。

アソシエーションの相手側のPKがポピュレートされていない理由を理解する必要がありますが、元の質問の範囲外です。

関連する問題