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

时间:2014-11-22 11:59:06

标签: postgresql express jointable bookshelf.js knex.js

假设我们有一个加入表vehicle_inspections和另一个加入表inspection_actions,以及actionsvehicles, and次检查的基本表。

假设我希望以下数据库条目:

 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

以及以下书架类

inspection_actions.js

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

vehicle_inspections.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;
         };
       }
     };
});

inspection.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条目时发生。似乎正在发生的是,outlook_action表没有通过嵌套的withRelated填充。我怎么能让这个有效的嵌套创建工作?

1 个答案:

答案 0 :(得分:5)

我并不完全清楚你想要达到的目标,但这就是我通常会如何设置的。首先我创建一个基本模型(假设它保存为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);

最后一个动作模型:

 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');
});