Search code examples
javascriptnode.jsdatabasebluebirdknex.js

Nested records insert with knex.js


We have a database schema as below:

students table

| id | name | address |


A student has multiple education histories.

education_histories table

| id | degree | university | student_id | #student_id is foreign key pointing student table


We get JSON structure from client side as like below:

{
    "name" :"Ram Neupane",
    "address": "Kathmandu, Bagmati",
    "education_histories": [
        {   
            "degree": "I.Sc.",
            "university": "Tribhuvan University"
        }, {
            "degree": "BE",
            "university": "Tribhuvan University"
        }
    ]
}

I am new to Node.js and Knex.js. I want to insert student and nested education history on database using bluebird promise with Knex. How can I solve this problem.

I have tried with following promise:

function create (jsonParam) {
    return new Promise(function (resolve, reject) {
      knex('students')
      .insert({name: jsonParam.name, address: jsonParam.address})
      .returning('id')
      .then(function (response) {
        # Here, I want to insert record to education_histories table
      })
      .catch(function (err) {
        reject(err);
      });
    })
  }

Solution

  • Sorry to answer my own question But I want to explain only that how do i solve.

    We can do the action by multiple ways

    1. With reference to Knex insert docs, we can directly inset multiple records to table by just placing the json object in array. So, we have jsonParam['education_histories'] which is an array, that containing education_history json object.

          var student_id = response[0];
          var educationHistoryParams = jsonParam['education_histories'];
      
          educationHistoryParams.forEach(function(educationHistory){
             educationHistory.student_id = student_id;
          });
      
          knex('education_histories').insert(educationHistoryParams)
          .then(resolve());
      
    2. Another way is by using Bluebird Promise.join API or Bluebird Promise.map API.

          var student_id = response[0];
          var educationHistoryParams = jsonParam['education_histories'];
      
          return Promise.join(
            educationHistoryParams.forEach(function (educationHistory) {
              educationHistory.student_id = student_id;
      
              new Promise(function (resolve, reject) {
                knex('education_histories').insert(educationHistory)
                .then(resolve())
                .catch(function (err) {
                  reject(err);
                })
              });
            });
          );