[BUG]: save() does not update Lucid models when the primary key is concerned

According to the documentation, calling save() on a model instance, AdonisJs is smart enough to guess whether it should perform an update or create a new database entry.

Try this:

const oldUserName = params.id
const user = await User.find(oldUserName) 
console.log(user.toJSON()) // Right record
const newUserName = 'begueradj'
user.username = newUserName
// This should perform an update
await user.save()

Actually no update is performed (and no instance is created)


  • username is the primary key here (but I think this should not be an issue)
  • save() performs the update when the primary key is not involved
  • This has other pesky implications such as hooks and setters not taking effect when the custom primary key is concerned

I know how to perform an update using qurey builder syntax, but I am curious to know whether this is a bug ?

I think this is the case (bug) and the issue is in the _update() function:

affected = await query
  .where(this.constructor.primaryKey, this.primaryKeyValue)

The culprit line is this one:

 .where(this.constructor.primaryKey, this.primaryKeyValue)

because this function searches for the record to update based on the primary key value whereas the new primaryKeyValue does not exist yet.

Hello there @begueradj

To properly save data into the database(insert/update) when the table doesn’t have a primary key or if it has a different name than the adonis defaults you should define it in the model. E.g.

class User extends Model {
    static get primaryKey() {
        return 'username' // => set here the name of your pk or set "return null" if you don't have a primary key

warm regards

1 Like

Yes, you are right but I did that in the related model, I just forgot to mention it here.
I reported this as a bug on GitHub and provided a production link.
Thank you for trying to help @bwmsites

Hi, just create a replica instance of the object.
Delete the old and create new row as the replica.

const oldUserName = params.id
const user = await User.find(oldUserName) 
const temp_user = user.toJSON()
const newUserName = 'begueradj'
temp_user.username = newUserName
await user.delete();
<your model name>.create(temp_user)