0

我正在设置一个我正在使用框架 AdonisJS 开发的新应用程序,我正在为我的模型创建种子和工厂,以便轻松地将数据手动播种到数据库。但是,我的模型彼此相关,并且在尝试实现完全播种时出现错误。我已经阅读了 Adonis 文档,但我还不清楚。

这是我尝试实现的架构示例:

示例架构

这是纯文本中的相同示例:

+-----------+  +-----------------+  +-----------------+  +-----------------+
| Model A   |  | Model B         |  | Model C         |  | Model D         |
+----+------+  +----+------------+  +----+------------+  +----+------------+
| PK | id   |  | PK | id         |  | PK | id         |  | PK | id         |
+----+------+  +----+------------+  +----+------------+  +----+------------+
|    | name |  |    | name       |  |    | name       |  |    | name       |
+----+------+  +----+------------+  +----+------------+  +----+------------+
|    |      |  | FK | model_A_id |  | FK | model_B_id |  | FK | model_C_id |
+----+------+  +----+------------+  +----+------------+  +----+------------+

如您所见,第一个模型(模型 A)与第二个模型(模型 B)具有一对多的关系,依此类推。我已经创建了一个迁移,并且我已经像这样关联了我的所有模型:

class ModelA extends Model {

    modelBs() {
        return this.hasMany('App/Models/ModelB')
    }
}

class ModelB extends Model {

    modelA() {
        return this.belongsTo('App/Models/ModelA')
    }

    modelCs() {
        return this.hasMany('App/Models/ModelC')
    }
}

// And so on with classes ModelC, and ModelD...

正如您在上面的代码中看到的那样,根据 AdonisJS 文档,必须首先完成才能在播种时创建关系。然后,我应该为每个模型创建工厂,如下所示:

// File: database/factory.js

// Model A blueprint
Factory.blueprint('App/Models/ModelA', (faker) => {
  return {
    name: faker.sentence()
  }
})

// Model B blueprint
Factory.blueprint('App/Models/ModelB', (faker) => {
  return {
    name: faker.sentence()
  }
})

// And so on with Models C and D...

最后,在我的名为 ModelASeeder.js 的种子文件中,我创建了所有模型之间的关系以将它们关联起来:

//File: database/seeds/ModelASeeder.js

const Factory = use('Factory')

class ModelASeeder {
  async run () {

    // I create only one Model A.
    const modelA_var = await Factory
      .model('App/Models/ModelA')
      .create()

    // Then I makeMany of Model B (4 of them).
    const modelB_var = await Factory
      .model('App/Models/ModelB')
      .makeMany(4)

    // As the documentation says, I associate them like so:

    await modelA_var.modelBs().save(modelB_var)


    // Then I want to assign Model C with the ModelBs that I associated to ModelA before, like so (I create 8 of them):

    const modelC_var = await Factory
      .model('App/Models/ModelC')
      .makeMany(8)

    // Then I try to assign ModelB to ModelC

    await modelB_var.modelCs().save(modelC_var)

    // And so on with the model D, etc, etc....

我面临一个我无法解决的问题。当我运行命令adonis seed时,我收到以下错误消息:

TypeError: relatedInstance.save is not a function
    at Proxy.save (/MyUser/User/my-app/node_modules/@adonisjs/lucid/src/Lucid/Relations/HasMany.js:165:28)

最后,它只播种第一个表(模型 A 表)而不是其余的表。所以我有两个问题:

首先,为什么我会收到这个错误?

其次,这是实现我的数据库播种目标的最佳方法吗?

非常感谢您抽出宝贵时间回答我的问题,如果我的描述有误,我的英语并不完美,对此我深表歉意。

4

1 回答 1

0

尝试使用saveMany()而不是 save()。要在hasManybelongsToMany

关系 中保留多个实例,您需要使用.saveMany()

文档: https ://adonisjs.com/docs/4.0/relationships#_savemany

于 2020-04-11T18:26:18.290 回答