在预先存在的数据库上定制多对多的热切加载

Bob*_*bby 0 mysql many-to-many eager-loading sequelize.js

我正在尝试使用Sequelize设置我现有的Express应用程序.在应用程序中,在用户登录时,我执行查询以尝试获取表示用户的对象以及来自少数几个表的几个关系.我已经使用多对多关系将我的测试下拉到以下最小化表示.

这是我的用户模型(在coffeescript中):

module.exports = (sequelize, DataTypes) ->
  sequelize.define "User",
    id:
      type: DataTypes.INTEGER(11)
      primaryKey: true
      autoIncrement: true

    email:
      type: DataTypes.STRING
      allowNull: false

  ,
    tableName: 'users'
    classMethods:
      associate: (models) ->
        @hasOne models.UserDetail
        @hasMany models.Plan,
          through: models.UserPlan
          foreignKey: 'user_id'
Run Code Online (Sandbox Code Playgroud)

这是我的计划模型:

module.exports = (sequelize, DataTypes) ->
  sequelize.define "Plan",
    id:
      type: DataTypes.INTEGER(11)
      primaryKey: true
      autoIncrement: true

    plan:
      type: DataTypes.STRING
      allowNull: false
  ,
    tableName: 'plans'
    classMethods:
      associate: (models) ->
        @hasMany models.User,
          through: models.UserPlan
          foreignKey: 'plan_id'
Run Code Online (Sandbox Code Playgroud)

而且,这是中间的"通过"表(user_plans):

module.exports = (sequelize, DataTypes) ->
  sequelize.define "UserPlan",
    user_id:
      type: DataTypes.INTEGER(11)
      allowNull: false
      primaryKey: true

    plan_id:
      type: DataTypes.INTEGER(11)
      allowNull: false
  ,
    tableName: 'user_plans'
Run Code Online (Sandbox Code Playgroud)

以下是我正在执行的发现,我希望能够使其正常工作:

          console.log JSON.stringify(u)
          db.User.find(
            where:
              id: u.id
            include: [
                model: db.Plan
                as: 'plan'
            ]
          )
          .success (user) ->
            console.log JSON.stringify(user)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我有一个非急切的加载对象'u'被删除到控制台,但后来查询.success调用永远不会发生,所以'用户'对象永远不会被转储到控制台.这是输出:

{"id":3,"email":"asdf@1234.com"}
[Error: Plan (plan) is not associated to User!]
Run Code Online (Sandbox Code Playgroud)

知道我可能做错了吗?一些讨论显示,这可能是过去使用现有表格的问题,但看起来这些问题已在最新版本的sequelize中得到解决.我正在运行~1.7.0(撰写本文时的最新版本).

任何帮助表示赞赏.

Jan*_*ier 9

as在包含指定的别名.设置关联时,还必须设置此别名.

几个例子:

User.hasMany(Plans) 
User.find({
  include: [
    { model: Plan }  // no as is allowed here, since we didnt specify it in the association
  ]
})

User.hasMany(Plans, { as: 'plans' }) 
User.find({
  include: [
    { model: Plan, as: 'plans' } // here you HAVE to specify the same alias as you did in your association
  ]
})
Run Code Online (Sandbox Code Playgroud)

作为一个更高级的示例,显示为什么必要,考虑相同的模型多次关联:

User.belongsTo(Plans, { as: 'currentPlans' }) // this is joined via planId on user
User.hasMany(Plans, { as: 'previousPlans' }) // this is stored in a join table
Plan.hasMany(User)

User.find({
  include: [
    { model: Plan } 
      /* If you dont specify an as here, sequelize has no way of knowing which 
         relation to load. Therefore the as should only be provided if you 
         set one in the association, and you should provide the exact same
         string as in the assocation.
      */ 
  ]
})
Run Code Online (Sandbox Code Playgroud)