Recently, I started diving into the Adonis framework (v5) and decided to build a todo list api as part of my learning process.
However, I'm facing an issue concerning the relationship between the User
and Todo
entities.
Let me show you the models for better understanding:
// 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 completed: 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) {
user.password = await Hash.make(user.password)
}
}
}
I omitted the migration files, but can provide them if necessary. The challenge here is that I expect to be able to save Users and Todo entries in the database while linking each todo entry to its respective author, following the documentation provided here.
To troubleshoot, I used the node ace repl
command like this:
// log of running the commands 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
>
The error message seems confusing because the author
attribute does exist in the Todo
model. Any ideas on how to resolve this issue and successfully run my todo app? Your help is greatly appreciated!
Thank you in advance!