Nodejs书架中的简单引用关系

Posted

技术标签:

【中文标题】Nodejs书架中的简单引用关系【英文标题】:Simple Referenced-by Relation in Nodejs Bookshelf 【发布时间】:2016-02-10 15:15:45 【问题描述】:

我在服务器中使用 Bookshelf 库作为 ORM,但在定义一个非常简单的关系时遇到了麻烦。

我有一个实用程序表,它被许多其他表引用,而这些表没有任何外键。

例如:

Languages 包含语言记录的表(id、值)

Posts 包含帖子数据和帖子语言的表(id, ...., language_id)

Users 包含用户数据和用户选择的语言(id、...、language_id)的表

还有其他一些具有相同逻辑的表 - 只是为 Language 表保留一个外键。

根据文档,belongsTo 方法的外键参数应该指向模型中定义它的字段。

所以我这样定义我的模型:

var Language = bookshelf.Model.extend(
  tableName: 'languages',
  idAttribute: 'LanguageID',

);

var Post = bookshelf.Model.extend(
   tableName: 'posts',
   idAttribute: 'PostID',

   Language: function() 
       return this.belongsTo(Language, 'LanguageID');
   ,
);

我的查询是:

 Post
   .where(PostID: 1)
   .fetch(withRelated:['Language'])
   .then(function(post) 
      console.log(JSON.stringify(post.related('Language')));
    );

错误信息是:

Unhandled rejection Error: A valid target model must be defined 
for the posts belongsTo relation

我尝试定义这些表和Languages 表之间的几乎所有其他可能的关系,但我不断收到有关未以正确方式定义关系的错误消息。

我怎样才能实现这种关系?

【问题讨论】:

找到任何答案/解决方案 【参考方案1】:

我无法重现您的确切错误消息,但您的代码可能与某处的大小写不匹配。

这是一个使用 SQLite3 的工作示例(节点 4.2.2,书架 0.9.1,knex 0.9.0 和 sqlite3 3.1.1):

sqlite3 data.sqlite3:

create table languages (languageid int primary key, name text);
create table posts(postid int primary key, languageid int, text text);
insert into languages values (1, 'english');
insert into languages values (2, 'german');
insert into posts values(1, 2, 'etwas geschrieben');
insert into posts values(2, 1, 'something written');
insert into posts values(3, 1, 'something else written');

在节点上:

var knex = require('knex')(client:'sqlite3',connection:filename: 'data.sqlite3');
var bookshelf = require('bookshelf')(knex);
var Language = bookshelf.Model.extend(tableName: 'languages', idAttribute: 'languageid');
var Post = bookshelf.Model.extend(tableName: 'posts', idAttribute: 'postid', Language: function()return this.belongsTo(Language,'languageid'););

Post.where(postid: 3).fetch(withRelated:['Language']).then(function(p) console.log(p.toJSON()););
// Outputs:
//  postid: 3,
//   languageid: 1,
//   text: 'something else written',
//   Language:  languageid: 1, name: 'english'  

Post.where(postid: 3).fetch(withRelated:['Language']).then(function(p) console.log(p.related('Language').toJSON()););
// Outputs: 
//  languageid: 1, name: 'english' 

如果我在 belongsTo() 上使用错误大小写的 languages 定义 Post:

var Post = bookshelf.Model.extend(tableName: 'posts', idAttribute: 'postid', Language: function()return this.belongsTo(language,'languageid'););
// note there was no error yet
Post.where(postid: 3).fetch(withRelated:['Language']).then(function(p) console.log(p.related('Language').toJSON()););
// Fails with: Unhandled rejection ReferenceError: language is not defined

另外,如果你定义的关系键的大小写与定义目标时使用的不同,它会默默地不匹配:

// note using `LanguageID` instead of `languageid`
var Post = bookshelf.Model.extend(tableName: 'posts', idAttribute: 'PostID', Language: function()return this.belongsTo(Language,'LanguageID'););
Post.where(PostID: 3).fetch(withRelated:['Language']).then(function(p) console.log(p.related('Language').toJSON()););
// Outputs and empty list (no matches!):
// 

因此,我建议您查看用于键的大小写和放置在关系子句中的对象名称。

【讨论】:

以上是关于Nodejs书架中的简单引用关系的主要内容,如果未能解决你的问题,请参考以下文章

书架中的SQL过滤器查询作为nodejs中的Laravel

全栈项目|小书架|服务器端-NodeJS+Koa2 实现点赞功能

全栈项目|小书架|服务器端-NodeJS+Koa2 实现书籍详情接口

全栈项目|小书架|服务器开发-NodeJS 中使用 Sequelize 操作 MySQL数据库

全栈项目|小书架|服务器端-NodeJS+Koa2实现首页图书列表接口

nodeJS中的Cookie和Session