Loopback“hasManyThrough”关系。在哪里添加?

时间:2014-09-30 10:54:03

标签: node.js loopbackjs

我有一个User实体和一个Hobbie实体,都在Loopback中定义了它们的模型,我在API资源管理器中看到它们。

我有一个UserHobbie表,它将User和Hobbie链接在ManyToMany关系中。我试图声明一个环回hasManyThrough关系,例如

User.hasMany(Hobbie, {through: UserHobbie});

但我似乎无法做得好,因为它并没有出现在资源管理器中。我在引导部分之后立即在/server/server.js中声明了它,并且我已尝试在/common/User.js/common/Hobbie.js中进行此操作(但在其中任何一个中,另一个,另一个模型不可见。

是否有正确的语法在User.json或Hobbie.json中添加?这将是我的首选方式,因为我在json定义中的任何内容都显示在资源管理器中。

2 个答案:

答案 0 :(得分:9)

要解决模型JSON中的问题,我将在下面概述解决方案。但是,使用" hasAndBelongsToMany"关系可以更简单地解决您的问题,我也将在下面概述。

在User.json中:

  "relations": {
    "Hobbies": {
      "type": "hasMany",
      "model": "Hobbie",
      "through": "UserHobbie",
      "foreignKey": "hobbieId"
    }
  }

在你的Hobbie.json中:

  "relations": {
    "Users": {
      "type": "hasMany",
      "model": "User",
      "through": "UserHobbie",
      "foreignKey": "userId"
    }
  }

你的UserHobbie.json看起来像这样(请注意,你不要在"属性"中定义userId或hobbieId:

{
  "name": "UserHobbie",
  "plural": "UserHobbies",
  "base": "PersistedModel",
  "properties": {
    "id": {
      "type": "String",
      "id": true
    }
  },
  "validations": [],
  "relations": {
    "Users": {
        "type": "belongsTo",
        "model": "User",
        "foreignKey": "userId"
    },
    "Hobbies": {
        "type": "belongsTo",
        "model": "Hobbie",
        "foreignKey": "hobbieId"
    }
  },
  "acls": [],
  "methods": []
}

这个简单的方法如下:

不要显着创建UserHobbies模型。 Loopback将自动为您创建一个Join模型。

在您的用户模型中:

  "relations": {
    "Hobbies": {
      "type": "hasAndBelongsToMany",
      "model": "Hobbie"
    }
  }

你内心的Hobbie模特:

  "relations": {
    "Users": {
      "type": "hasAndBelongsToMany",
      "model": "User"
    }
  }

如果你想在代码中执行此操作,那么你是正确的,有一些Bootstrap时序问题可以防止这些关系出现在资源管理器中。我将很快添加另一个回复,向您展示如何使这项工作。

答案 1 :(得分:3)

现在,为了让您在资源管理器中显示创建关系的原始基于代码的实现,这是您应该做的。

首先,从你的Loopback Projects的./server/boot目录中,移动" explorer.js"到./server(其中server.js在项目中。

./server/server.js的最后一部分看起来应该是这样的(为了简洁起见,我已经删除了一些评论。

boot(app, __dirname);

... // Removed for brevity

app.use(loopback.urlNotFound());

// The ultimate error handler.
app.use(loopback.errorHandler());

app.start = function() {
  // start the web server
  return app.listen(function() {
    app.emit('started');
    console.log('Web server listening at: %s', app.get('url'));
  });
};

// start the server if `$ node server.js`
if (require.main === module) {
  app.start();
}

现在编辑.server / server.js的最后一部分看起来像这样:

boot(app, __dirname);
    // We took explorer.js out of /boot and put it in /server root next to server.js


var programmaticLoopbackSetup = require('./programmaticLoopbackSetup');
    // If the User has any special Programmatic Loopback Setup (create Model Relationships, etc.) do it first

if (programmaticLoopbackSetup !== undefined) {
    programmaticLoopbackSetup(app, finishUp);
}
else {
    finishUp();  // If you didn't want any Code based Setup
}

// Defer all the rest of the Startup Work until Explorer 
// has all the Model Info it needs from any Async or Programmatic Setup.
function finishUp() {

    require('./explorer')(app);
        // This was formerly done within "boot" above...

        ...  // removed for brevity...

    // Requests that get this far won't be handled
    // by any middleware. Convert them into a 404 error
    // that will be handled later down the chain.
    app.use(loopback.urlNotFound());

    // The ultimate error handler.
    app.use(loopback.errorHandler());

    app.start = function() {
      // start the web server
      return app.listen(function() {
        app.emit('started');
        console.log('Web server listening at: %s', app.get('url'));
      });
    };

    // start the server if `$ node server.js`
    if (require.main === module) {
      app.start();
    }
}

在./server/programmaticLoopbackSetup.js中添加一个新文件,使其看起来如下所示(注意在#34之后如何调用它;启动"并在最终确定应用程序初始化之前

module.exports = function programmaticLoopbackSetup(app, next) {
    var User = app.models.User;
    var Hobbie = app.models.Hobbie;


    // This Block Below Creates a Many to Many User / Hobbie Relationship directly 

        User.hasAndBelongsToMany(Hobbie);
        Hobbie.hasAndBelongsToMany(User);

    next();  // Callback to finish App Init...
};

您将在资源管理器中看到用户/ Hobbie关系(使用" hasAndBelongsToMany"在这种情况下)。在programmaticLoopbackSetup.js中执行基于代码的LoopBack模型,数据源或其他改进