loopback:如何根据关系的属性加载模型实例

时间:2015-12-11 23:21:18

标签: javascript tags has-many-through loopback

我有一个模型Book

Book可以包含多个代码,因此TagBookTags有一个hasMany关系

现在,如何使用标记"历史记录"加载所有Book个实例(例如)? 它应该是微不足道的,但我无法找到答案。

在文档中,只有属性值的示例(如字符串,布尔值等),但没有通过关系加载的示例。有include过滤器可以加载关系,但这应该适用于加载关系实例,这是其他的东西(AFAI理解);

我试过了:

Book.find({
    where: {tags: {name: "history"}}
}, function(err, books) {
}

但这根本不起作用。 我的下一个赌注是尝试通过id加载Tag并尝试按对象过滤,但我甚至不知道该怎么做,因为没有"包含" where子句文档中的运算符: https://docs.strongloop.com/display/public/LB/Where+filter#Wherefilter-inq

最终的解决方法是:

  • 通过名称加载标记
  • 使用该标记ID加载所有BookTags个实例,获取图书ID
  • 加载所有包含这些ID的图书

似乎很麻烦,并建议应该有一个更优雅的解决方案?

1 个答案:

答案 0 :(得分:0)

如果一本书可以有很多标签,并且标签可以有很多书,那么听起来你需要hasAndBelongsToMany关系。这种关系非常适用于没有任何额外负载的多对多。

<强>公共/模型/ book.json

{
  "name": "Book",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "Title": {
      "type": "string",
      "required": true
    },
    "Author": {
      "type": "string"
    }
  },
  "validations": [],
  "relations": {
    "tags": {
      "type": "hasAndBelongsToMany",
      "model": "Tag",
      "foreignKey": ""
    }
  },
  "acls": [],
  "methods": {}
}

<强>公共/模型/ tag.json

{
  "name": "Tag",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "Name": {
      "type": "string",
      "required": true
    }
  },
  "validations": [],
  "relations": {
    "books": {
      "type": "hasAndBelongsToMany",
      "model": "Book",
      "foreignKey": ""
    }
  },
  "acls": [],
  "methods": {}
}

如何访问它?这是一个示例启动脚本,可以创建一些标签和书籍,并访问它们。

服务器/引导/ seed.js

var async = require('async');
module.exports = function(app) {

    var Tag = app.models.Tag;
    var Book = app.models.Book;

    var tags = [{Name: "Scifi"}, {Name: "Adventure"}];

    Book.create({Title: "Twenty Thousand Leagues Under the Sea", author: "Jules Verne"}, function(err, book){
        console.log('Book: ' + book);

        async.each(tags, function(tag, done){
            book.tags.create(tag, done);
        }, function(err){
            //Book > Tag
            console.log("Book " + book.Title + " has these tags: ");
            console.log(book.tags())
            //Tag > Book

            Tag.findOne({where: {Name: "Scifi"}, include: 'books'},function(err, foundTag){
                console.log("    - Tag " + foundTag.Name + " has these books:");
                console.log(foundTag.books());

            });
        });
    });
};

输出:

Book Twenty Thousand Leagues Under the Sea has these tags: 
[ { Name: 'Scifi', id: 1 }, { Name: 'Adventure', id: 2 } ]

Tag Scifi has these books:
[ { 
    Title: 'Twenty Thousand Leagues Under the Sea',
    author: 'Jules Verne',
    id: 1 
} ]