【问题标题】:Simple Referenced-by Relation in Nodejs BookshelfNodejs书架中的简单引用关系
【发布时间】: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 表之间的几乎所有其他可能的关系,但我不断收到有关未以正确方式定义关系的错误消息。

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

【问题讨论】:

  • 找到任何答案/解决方案

标签: node.js orm bookshelf.js


【解决方案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!):
// {}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 2013-06-12
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多