Objection.js急切的多对多关系问题
Objection.js eager many-to-many relationship problems
每当尝试使用预先加载获取 Objection.js
中的用户组时,我都会收到以下错误:
错误
TypeError: Cannot read property 'size' of null
at findRelationPropsToSelect (/vagrant/node_modules/objection/lib/queryBuilder/operations/eager/WhereInEagerOperation.js:184:36)
at WhereInEagerOperation.onBuild (/vagrant/node_modules/objection/lib/queryBuilder/operations/eager/WhereInEagerOperation.js:35:48)
at QueryBuilder.callOperationMethod (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilderOperationSupport.js:353:33)
at forEachOperation.op (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilderOperationSupport.js:449:14)
at QueryBuilder.forEachOperation (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilderOperationSupport.js:287:13)
at QueryBuilder.executeOnBuild (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilderOperationSupport.js:447:10)
at QueryBuilder.buildInto (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilderOperationSupport.js:440:10)
at buildInto (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilder.js:1361:25)
at doExecute (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilder.js:1265:23)
at Bluebird.try.then (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilder.js:583:19)
at tryCatcher (/vagrant/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/vagrant/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/vagrant/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/vagrant/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/vagrant/node_modules/bluebird/js/release/promise.js:694:18)
at _drainQueueStep (/vagrant/node_modules/bluebird/js/release/async.js:138:12)
我的迁移和种子都是 运行 正确的,当我通过 PSequel 连接时可以看到它们。我一定是在做一些愚蠢的事情,但作为 Objection.js 的新手,我看不到它。
型号
我的模型如下:
// models/base.model.js
import { Model } from 'objection';
export class BaseModel extends Model {
static modelPaths = [__dirname];
}
// models/user.model.js
import { Model } from 'objection';
import { BaseModel } from './base.model'
export class User extends BaseModel {
static tableName = 'users';
static relationMappings = {
groups: {
relation: Model.ManyToManyRelation,
join: {
from: 'users.id',
through: {
from: 'users_groups.user_id',
to: 'users_groups.group_id'
},
to: 'groups.id'
}
}
}
}
// models/group.model.js
import { Model } from 'objection';
import { BaseModel } from './base.model';
export class Group extends BaseModel {
static tableName = 'groups';
static relationMappings = {
users: {
relation: Model.ManyToManyRelation,
join: {
from: 'groups.id',
through: {
from: 'users_groups.user_id',
to: 'users_groups.group_id'
},
to: 'users.id',
}
}
}
}
迁移
我的迁移如下:
// migrations/20190307214041-create-users-table.js
exports.up = function(knex) {
return knex.schema
.createTable('users', function(table) {
table.increments('id').primary();
table.string('firstName').notNullable();
table.string('lastName').notNullable();
table.string('avatar').nullable();
table.string('email').notNullable();
table.string('password').notNullable();
table.integer('active').notNullable().defaultTo(0);
table.timestamps();
table.unique('email');
});
};
exports.down = function(knex) {
return knex.schema
.dropTable('users');
};
// migrations/20190307214814-create-groups-table.js
exports.up = function(knex) {
return knex.schema
.createTable('groups', function(table) {
table.increments('id').primary();
table.string('name');
table.integer('active');
table.timestamps();
});
};
exports.down = function(knex) {
return knex.schema
.dropTable('groups');
};
// migrations/20190307220010-create-groups_users-table.js
exports.up = function(knex) {
return knex.schema
.createTable('users_groups', function(table) {
// table.increments('id').primary();
table.integer('user_id');
table.integer('group_id');
// table.integer('users_id').references('users.id');
// table.integer('groups_id').references('groups.id');
});
};
exports.down = function(knex) {
return knex.schema
.dropTable('users_groups');
};
查询示例
工作查询[=37=]
此查询工作正常,我取回了数据。
try {
const users = await User.query().orderBy('id');
res.status(200).json(users);
} catch (err) {
console.error(err);
res.status(500).json({ message: 'There was an error' });
}
查询失败
这个查询失败了,我得到了这个问题顶部显示的错误。
try {
const user = await User.query()
.where('id', Number(req.params.id))
.eager('groups');
res.status(200).json(user);
} catch (err) {
console.error(err);
res.status(500).json({ message: 'There was an error' });
}
原来是babel配置问题。
当我将代码更改为如下所示时,它起作用了:
import path from 'path';
import { Model } from 'objection';
import { BaseModel } from './base.model';
export class Group extends BaseModel {
static get tableName() {
return 'groups';
}
static get relationMappings() {
return {
users: {
modelClass: path.join(__dirname, 'user.model'),
relation: Model.ManyToManyRelation,
join: {
from: 'groups.id',
through: {
from: 'users_groups.group_id',
to: 'users_groups.user_id'
},
to: 'users.id',
}
}
};
}
}
import path from 'path';
import { Model } from 'objection';
import { BaseModel } from './base.model'
export class User extends BaseModel {
static get tableName() {
return 'users';
}
static get relationMappings() {
return {
groups: {
modelClass: path.join(__dirname, 'group.model'),
relation: Model.ManyToManyRelation,
join: {
from: 'users.id',
through: {
from: 'users_groups.user_id',
to: 'users_groups.group_id'
},
to: 'groups.id'
}
}
};
}
}
每当尝试使用预先加载获取 Objection.js
中的用户组时,我都会收到以下错误:
错误
TypeError: Cannot read property 'size' of null
at findRelationPropsToSelect (/vagrant/node_modules/objection/lib/queryBuilder/operations/eager/WhereInEagerOperation.js:184:36)
at WhereInEagerOperation.onBuild (/vagrant/node_modules/objection/lib/queryBuilder/operations/eager/WhereInEagerOperation.js:35:48)
at QueryBuilder.callOperationMethod (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilderOperationSupport.js:353:33)
at forEachOperation.op (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilderOperationSupport.js:449:14)
at QueryBuilder.forEachOperation (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilderOperationSupport.js:287:13)
at QueryBuilder.executeOnBuild (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilderOperationSupport.js:447:10)
at QueryBuilder.buildInto (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilderOperationSupport.js:440:10)
at buildInto (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilder.js:1361:25)
at doExecute (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilder.js:1265:23)
at Bluebird.try.then (/vagrant/node_modules/objection/lib/queryBuilder/QueryBuilder.js:583:19)
at tryCatcher (/vagrant/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/vagrant/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/vagrant/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/vagrant/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/vagrant/node_modules/bluebird/js/release/promise.js:694:18)
at _drainQueueStep (/vagrant/node_modules/bluebird/js/release/async.js:138:12)
我的迁移和种子都是 运行 正确的,当我通过 PSequel 连接时可以看到它们。我一定是在做一些愚蠢的事情,但作为 Objection.js 的新手,我看不到它。
型号
我的模型如下:
// models/base.model.js
import { Model } from 'objection';
export class BaseModel extends Model {
static modelPaths = [__dirname];
}
// models/user.model.js
import { Model } from 'objection';
import { BaseModel } from './base.model'
export class User extends BaseModel {
static tableName = 'users';
static relationMappings = {
groups: {
relation: Model.ManyToManyRelation,
join: {
from: 'users.id',
through: {
from: 'users_groups.user_id',
to: 'users_groups.group_id'
},
to: 'groups.id'
}
}
}
}
// models/group.model.js
import { Model } from 'objection';
import { BaseModel } from './base.model';
export class Group extends BaseModel {
static tableName = 'groups';
static relationMappings = {
users: {
relation: Model.ManyToManyRelation,
join: {
from: 'groups.id',
through: {
from: 'users_groups.user_id',
to: 'users_groups.group_id'
},
to: 'users.id',
}
}
}
}
迁移
我的迁移如下:
// migrations/20190307214041-create-users-table.js
exports.up = function(knex) {
return knex.schema
.createTable('users', function(table) {
table.increments('id').primary();
table.string('firstName').notNullable();
table.string('lastName').notNullable();
table.string('avatar').nullable();
table.string('email').notNullable();
table.string('password').notNullable();
table.integer('active').notNullable().defaultTo(0);
table.timestamps();
table.unique('email');
});
};
exports.down = function(knex) {
return knex.schema
.dropTable('users');
};
// migrations/20190307214814-create-groups-table.js
exports.up = function(knex) {
return knex.schema
.createTable('groups', function(table) {
table.increments('id').primary();
table.string('name');
table.integer('active');
table.timestamps();
});
};
exports.down = function(knex) {
return knex.schema
.dropTable('groups');
};
// migrations/20190307220010-create-groups_users-table.js
exports.up = function(knex) {
return knex.schema
.createTable('users_groups', function(table) {
// table.increments('id').primary();
table.integer('user_id');
table.integer('group_id');
// table.integer('users_id').references('users.id');
// table.integer('groups_id').references('groups.id');
});
};
exports.down = function(knex) {
return knex.schema
.dropTable('users_groups');
};
查询示例
工作查询[=37=]
此查询工作正常,我取回了数据。
try {
const users = await User.query().orderBy('id');
res.status(200).json(users);
} catch (err) {
console.error(err);
res.status(500).json({ message: 'There was an error' });
}
查询失败
这个查询失败了,我得到了这个问题顶部显示的错误。
try {
const user = await User.query()
.where('id', Number(req.params.id))
.eager('groups');
res.status(200).json(user);
} catch (err) {
console.error(err);
res.status(500).json({ message: 'There was an error' });
}
原来是babel配置问题。
当我将代码更改为如下所示时,它起作用了:
import path from 'path';
import { Model } from 'objection';
import { BaseModel } from './base.model';
export class Group extends BaseModel {
static get tableName() {
return 'groups';
}
static get relationMappings() {
return {
users: {
modelClass: path.join(__dirname, 'user.model'),
relation: Model.ManyToManyRelation,
join: {
from: 'groups.id',
through: {
from: 'users_groups.group_id',
to: 'users_groups.user_id'
},
to: 'users.id',
}
}
};
}
}
import path from 'path';
import { Model } from 'objection';
import { BaseModel } from './base.model'
export class User extends BaseModel {
static get tableName() {
return 'users';
}
static get relationMappings() {
return {
groups: {
modelClass: path.join(__dirname, 'group.model'),
relation: Model.ManyToManyRelation,
join: {
from: 'users.id',
through: {
from: 'users_groups.user_id',
to: 'users_groups.group_id'
},
to: 'groups.id'
}
}
};
}
}