postgresql - BookshelfJs 无法在创建时引入嵌套关系

标签 postgresql express join bookshelf.js knex.js

假设我们有一个连接表 vehicle_inspections 和另一个连接表 inspection_actions,以及 actionsvehicles 的基本表和检查`。

假设我想要以下数据库条目:

 vehicles
 ----------------------------
 id        make
 ----------------------------
 1         Toyota



actions
-------------------------------
id        description
-------------------------------
2         Check Tire Pressue

inspections
-------------------------------
id        location        date
-------------------------------
3         New York      tomorrow

vehicle_inspections
--------------------------------
vehicle_id      inspection_id   
--------------------------------
1                3

inspection_actions
--------------------------------
inspection_id     action_id
--------------------------------
3                 2

和下面的书架类

检查 Action .js

(function () {
    'use strict';
     var Repository = require('../repository');
     module.exports = Repository.Model.extend({
       tableName: 'inspection_actions',
     });  
})();

车辆检查.js

(function () {
    'use strict';
     var Repository = require('../repository');

     module.exports = Repository.Model.extend({
       tableName = 'vehicle_inspections',
       inspection: function () {
         return this.belongsTo(require('inspection'));
       },
       fetchOrCreate: function(vehicleId, inspectionId, options) {
         var self = this;
         return self.query(function (qb) {
           qb.where({
             vehicle_id: vehicleId,
             inspection_id: inspectionId
           });
         )}.fetch(options || {}).then(function (model) {
           if (!model) {
             model.save({
               vehicle_id: vehicleId,
               inspection_id: inspectionId
             });
           return model;
         };
       }
     };
});

检查.js

...
module.exports = Repository.Model.extend(_.extend({
   tableName: 'inspections',
   actions: function () {
     return this.hasMany(require('./inspection-action'));
   }
}));

还有一条路线:

 new VehicleInspection().fetchOrCreate(req.params.vehicle_id, req.params.inspection_id, {withRelated: ['inspection.actions']})
 .then(function (vehicleInspection) {
    var inspection = vehicleInspection.related('inspection');
    console.log( inspection);
    console.log(inspection.related(actions);
  })

检查控制台日志打印出正确的检查,然而,与数据库中的内容无关,第二个 console.log 打印出空结果

 { length: 0,
  models: [],
 _byId: {},
   ...
  targetIdAttribute: 'id',
 foreignKey: undefined,
 parentId: undefined,
 parentTableName: 'tasks',
 parentIdAttribute: 'id',
 parentFk: undefined } }

这种“不良”行为只会在第一次创建 projectTasks 条目时发生。似乎正在发生的是 inspection_action 表未通过嵌套的 withRelated 填充。我怎样才能让这个有效的嵌套创建工作?

最佳答案

我不完全清楚您要实现的目标,但这是我通常的设置方式。首先我会创建一个基础模型(假设它保存为 base.js),我认为你会遇到一些循环依赖问题,所以使用 Bookshelf 注册表插件会很好:

var config = {
  client: // whatever client you are using,
  connection: // url to your database
};
var db = require('knex')(config);
var Bookshelf = require('bookshelf')(db);
var Base = Bookshelf.Model.extend({
   // Put anything here that will be helpful for your use case
});
Bookshelf.plugin('registry');

Base.model = Bookshelf.model.bind(Bookshelf);
module.exports = Base;

接下来创建您的车辆模型:

 require('inspection');
 require('action');
 var Base = require('base');

 var Vehicle = Base.Model.extend({
   tableName = 'vehicles',
   inspections: function () {
     return this.belongsToMany('Inspection',
       'inspections_vehicles', 'vehicle_id', 'inspection_id');
   },
   actions: function() {
     return this.belongsToMany('Action',
       'actions_vehicles', 'vehicle_id', 'action_id');

   }
 };
 module.exports = Base.model('Vehicle', Vehicle);

然后是检查模型:

 require('vehicle');
 var Base = require('base');

 var Inspection = Base.Model.extend({
   tableName = 'inspection',
   vehicles: function () {
     return this.belongsToMany('Vehicle',
       'inspections_vehicles', 'inspection_id', 'vehicle_id');
     }
 };
 module.exports = Base.model('Inspection', Inspection);

最后是一个 Action 模型:

 var Base = require('base');

 var Action = Base.Model.extend({
   tableName = 'actions',
 };
 module.exports = Base.model('Action', Action);

现在假设数据库尚未填充您提供的数据,我们可以填充它:

var Inspection = require('inspection');
var Vehicle = require('vehicle');
var Action = require('action');
var toyota;
var newYorkInspection

Vehicle.forge().save({name: 'Toyota'})
  .then(function(vehicle) {
    toyota = vehicle;   
    return Inspection.forge().save({location: 'New York', date: 'Tomorrow'});      
  }).then(function(inspection){
    newYorkInspection = inspection;
    return toyota.inspections().attach(newYorkInspection);
  }).then(function() {
    return Action.forge().save({description: 'Check Tire Pressure'});
  }).then(function(tirePressureAction) {
    return toyota.actions().attach(tirePressureAction);
  });

现在我可以通过相关操作和检查获取丰田汽车:

var Vehicle = require('vehicle');
return Vehicle.forge({'name': 'Toyota'}).fetch({
  withRelated: ['inspections', 'actions']
}).then(function(toyota){
  var toyotaInspections = toyota.related('inspections');
  var toyotaActions = toyota.related('actions');
});

关于postgresql - BookshelfJs 无法在创建时引入嵌套关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27077118/

相关文章:

api - Electron 作为响应 http 请求的本地 API 服务器?

mysql - 编写 SQL 查询

python - 在自定义函数上加入两个 RDD - SPARK

postgresql - 使用 liquibase 创建类型为 double precision[] 的列

mysql - 为 Rails 使用 2 个数据库 : MySQL or SQLite for Testing and Developmnet and PostgreSQL for Production

node.js - NodeJS - 在使用 multer 上传多个文件之前验证扩展名?

javascript - Expressjs 使用对象标题作为动态 url

java - 没有单独的连接表的 Hibernate @OneToMany

sql - 如何释放可能的 Postgres 行锁?

ruby - 使用 grape API 将复杂的 JSON 发布到 PostgreSQL