最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Adonis JS v5 relationship missing model attribute - Stack Overflow

programmeradmin2浏览0评论

I am learning how to use the Adonis framework (v5) and as the tradition dictates it, I am creating a todo list api to test it out.

The problem I am having is regarding the relationship between the User and Todo entities.

Here are the two models:

// file: app/Models/Todo.ts

export default class Todo extends BaseModel {
  @column({ isPrimary: true })
  public id: number

  @belongsTo(() => User, {
    foreignKey: 'id',
  })
  public author: BelongsTo<typeof User>

  @column()
  public pleted: boolean

  @column()
  public title: string

  @column()
  public description: string | null

  @column.dateTime({ autoCreate: true })
  public createdAt: DateTime

  @column.dateTime({ autoCreate: true, autoUpdate: true })
  public updatedAt: DateTime
}
// file: app/Models/User.ts

export default class User extends BaseModel {
  @column({ isPrimary: true })
  public id: number

  @column()
  public username: string

  @column({ serializeAs: null })
  public password: string

  @hasMany(() => Todo, {
    foreignKey: 'author',
  })
  public todos: HasMany<typeof Todo>

  @column.dateTime({ autoCreate: true })
  public createdAt: DateTime

  @column.dateTime({ autoCreate: true, autoUpdate: true })
  public updatedAt: DateTime

  @beforeSave()
  public static async hashPassword(user: User) {
    if (user.$dirty.password) {
      // Only hash password if required
      user.password = await Hash.make(user.password)
    }
  }
}

I did not include the migrations files but I will edit this question if they are needed.

What I am expecting is that I should be able to create and save Users into my database, the same for Todo entries and link the todo entries to their author. The documentation provides us with an example but I don't see where I am doing something wrong.

So to test it out I am using the node ace repl mand as follow:

// log of running the mands in the AdonisJS v5 REPL
> loadModels()
recursively reading models from "app/Models"
Loaded models module. You can access it using the "models" variable
> undefined
> const testUser = await models.User.create({ username: 'testUser', password: 'password' })
undefined
> await testUser.related('todos').create({ title: 'Example todo entry' })
Uncaught:
Exception: E_MISSING_MODEL_ATTRIBUTE: "User.todos" expects "author" to exist on "Todo" model, but is missing
    at <my-app-directory>\REPL23:1:39
    at Proxy.related (<my-app-directory>\node_modules\@adonisjs\lucid\build\src\Orm\BaseModel\index.js:1436:18)
    at HasMany.boot (<my-app-directory>\node_modules\@adonisjs\lucid\build\src\Orm\Relations\HasMany\index.js:74:12)
    at KeysExtractor.extract (<my-app-directory>\node_modules\@adonisjs\lucid\build\src\Orm\Relations\KeysExtractor.js:28:39)
    at Array.reduce (<anonymous>)
    at <my-app-directory>\node_modules\@adonisjs\lucid\build\src\Orm\Relations\KeysExtractor.js:32:23
>

I don't understand the error message since author actually exists on the Todo model.

How can I solve this problem and get my todo app up and running?

Thank you by advance!

I am learning how to use the Adonis framework (v5) and as the tradition dictates it, I am creating a todo list api to test it out.

The problem I am having is regarding the relationship between the User and Todo entities.

Here are the two models:

// file: app/Models/Todo.ts

export default class Todo extends BaseModel {
  @column({ isPrimary: true })
  public id: number

  @belongsTo(() => User, {
    foreignKey: 'id',
  })
  public author: BelongsTo<typeof User>

  @column()
  public pleted: boolean

  @column()
  public title: string

  @column()
  public description: string | null

  @column.dateTime({ autoCreate: true })
  public createdAt: DateTime

  @column.dateTime({ autoCreate: true, autoUpdate: true })
  public updatedAt: DateTime
}
// file: app/Models/User.ts

export default class User extends BaseModel {
  @column({ isPrimary: true })
  public id: number

  @column()
  public username: string

  @column({ serializeAs: null })
  public password: string

  @hasMany(() => Todo, {
    foreignKey: 'author',
  })
  public todos: HasMany<typeof Todo>

  @column.dateTime({ autoCreate: true })
  public createdAt: DateTime

  @column.dateTime({ autoCreate: true, autoUpdate: true })
  public updatedAt: DateTime

  @beforeSave()
  public static async hashPassword(user: User) {
    if (user.$dirty.password) {
      // Only hash password if required
      user.password = await Hash.make(user.password)
    }
  }
}

I did not include the migrations files but I will edit this question if they are needed.

What I am expecting is that I should be able to create and save Users into my database, the same for Todo entries and link the todo entries to their author. The documentation provides us with an example but I don't see where I am doing something wrong.

So to test it out I am using the node ace repl mand as follow:

// log of running the mands in the AdonisJS v5 REPL
> loadModels()
recursively reading models from "app/Models"
Loaded models module. You can access it using the "models" variable
> undefined
> const testUser = await models.User.create({ username: 'testUser', password: 'password' })
undefined
> await testUser.related('todos').create({ title: 'Example todo entry' })
Uncaught:
Exception: E_MISSING_MODEL_ATTRIBUTE: "User.todos" expects "author" to exist on "Todo" model, but is missing
    at <my-app-directory>\REPL23:1:39
    at Proxy.related (<my-app-directory>\node_modules\@adonisjs\lucid\build\src\Orm\BaseModel\index.js:1436:18)
    at HasMany.boot (<my-app-directory>\node_modules\@adonisjs\lucid\build\src\Orm\Relations\HasMany\index.js:74:12)
    at KeysExtractor.extract (<my-app-directory>\node_modules\@adonisjs\lucid\build\src\Orm\Relations\KeysExtractor.js:28:39)
    at Array.reduce (<anonymous>)
    at <my-app-directory>\node_modules\@adonisjs\lucid\build\src\Orm\Relations\KeysExtractor.js:32:23
>

I don't understand the error message since author actually exists on the Todo model.

How can I solve this problem and get my todo app up and running?

Thank you by advance!

Share Improve this question asked Aug 5, 2021 at 8:21 AmiralBl3ndicAmiralBl3ndic 4165 silver badges14 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 8

The error is that you are missing a field inside your model.

You need to define all fields with the @column() decorator. In your example, you are not defining the column author.

When creating a relation, you must have one column (the FK) and one relation.

If we assume that you have a column user_id inside your todos table, then you need to add the column user_id inside your Todo model.

Here is a correct example:

class User extends BaseModel {
  // ...
  @hasMany(() => Todo)
  todos: HasMany<typeof Todo>
}

class Todo extends BaseModel {
  @column()
  user_id: number

  @belongsTo(() => User)
  author: BelongsTo<typeof User>
}
发布评论

评论列表(0)

  1. 暂无评论