Update or create entity of 1-1 relationship in lucid


#1

Hey, what is the best way to do an upsert on a 1-1 belongsTo relationship. In following example, one user has one address at most. The user_id is the fkey of the the address table.

class User extends Model {
  address(){
    return this.hasOne('App/Models/Address');
  }
}

class Address extends Model {
  user(){
     return this.belongsTo('App/Models/User');
  }
}

// inside the update of the UserController
const user = await auth.getUser()
await user.address().create({ country: 'US' }); // <-- this will create multiple addresses if called more than once. I would like to update an existing address or insert.

#2

Why are you using hasOne if a user can have multiple addresses?

An Adress belongs to a user

  class Address .....
  ....
  user() {
    return this.belongsTo('App/Models/User');
  }

And a User hasMany Addresses

  class User ....
  ...
  addresses() {
    return this.hasMany('App/Models/Address');
  }

To create multiple address within your store method checkout thecreateMany lucid docs

....
// Object which contains your multiple addresses which will be stored in your User model
const address = {
  ....
}
// call createMany on the User model with your addresses object from above
await user.addresses().createMany(addresses);

If you want to update an existing one check if a record exist and call the lucid fill method.


#3

Thank you. One user always has one address. I’ll use modelInstance.merge() or modelInstance.fill. I was hoping there would be an easier way to perform upserts that didn’t require me to check if the address exists first.


#4

Then you should maybe consider another Database structure. For example one Table for the default address and another Table for all additional addresses.

That’s how i would do it i think. It’s almost the same with all those E-Commerce systems. You have one default address, but many shipping addresses for example.

Or if you use only one table, each address has a boolean if it’s the default address or something like that.

You can use fill if you create a new one, or merge to update a model.