书架查询

Querying with Bookshelf

我最近开始使用 Bookshelf。文档中的示例对我来说不是很清楚。这是一个这样的例子:

var knex = require('knex')({
  client: 'mysql',
  connection: process.env.MYSQL_DATABASE_CONNECTION
});
var bookshelf = require('bookshelf')(knex);

var User = bookshelf.Model.extend({
  tableName: 'users',
  posts: function() {
    return this.hasMany(Posts);
  }
});

var Posts = bookshelf.Model.extend({
  tableName: 'messages',
  tags: function() {
    return this.belongsToMany(Tag);
  }
});

var Tag = bookshelf.Model.extend({
  tableName: 'tags'
})

User.where('id', 1).fetch({
  withRelated: ['posts.tags']
}).then(function(user) {
  console.log(user.related('posts').toJSON());
}).catch(function(err) {
  console.error(err);
});

创建三个模型(用户、帖子和标签)后 - 有一个查询。

  1. 这个查询到底是什么意思?

    User.where('id', 1).fetch({withRelated: ['posts.tags']}).then(function(user) {
      console.log(user.related('posts').toJSON());
    }).catch(function(err) {
      console.error(err);
    });
    
  2. 什么是withRelated'posts.tags'user.related('posts')?谁能用最简单的形式告诉我这些术语是什么以及它们来自哪里?

  3. 最后,完整的查询是什么意思?

文档中都有答案,虽然不是所有的都在完全相同的地方,所以我能理解你的困惑。您真的必须阅读整篇文章才能更好地理解它。

来自documentation of Model.fetch()

withRelated: Relations to be retrieved with Model instance. Either one or more relation names (...) A single property, or an array of properties can be specified as a value for the withRelated property.

来自 Collection.fetch():

The withRelated option may be specified to fetch the models of the collection, eager loading any specified relations named on the model.

来自 Collection.load():

... Nested eager loads can be specified by separating the nested relations with .

来自 Model.related():

The related method returns a specified relation loaded on the relations hash on the model, or calls the associated relation method and adds it to the relations hash if one exists and has not yet been loaded.

所有这些都涉及在模型上预先加载关系。

这些方法的作用是以某种方式从与父模型的 table 相关的 table 加载一些数据。在您发布的示例中,用户模型有一些帖子,帖子本身有一些标签,所以关系是这样的:

User
  |_ Post
       |_ Tag

这些在每个模型上都表示为方法,例如,posts: function() { ... } 在用户模型中。

当您使用 withRelated 指定与预加载的关系时,您使用这些方法名称。此外,您可以通过使用 . 分隔深度嵌套关系来加载它们,这就是您在示例中看到的内容。

因此,将所有内容放在一起,该示例所做的就是搜索 id = 1 的用户,并检索属于该用户的所有帖子以及属于该用户的所有帖子的所有标签属于用户。

然后使用模型的 related('something') 方法访问这些相关对象。