One To One

A one-to-one relationship is a very basic relation. For example, a User model might be associated with one Phone. You may define such a relationship using 2 types of relationship attributes, hasOne and belongsTo.

Defining The One To One Relationship

To define this relationship, for example, a User model might be associated with one Phone, we define a hasOne field to the User model.

class User extends Model {
  static entity = 'users'
  static fields () {
    return {
      id: this.attr(null),
      name: this.string(''),
      phone: this.hasOne(Phone, 'userId')
    }
  }
}
class Phone extends Model {
  static entity = 'phones'
  static fields () {
    return {
      id: this.attr(null),
      userId: this.attr(null),
      number: this.string('')
    }
  }
}

The first argument passed to the hasOne method is the name of the model, and the second argument is the foreign key.

Additionally, Pinia ORM assumes that the foreign key should have a value matching the id (or the custom static primaryKey) field of the parent. In other words, Pinia ORM will look for the value of the user's id field in the userId field of the Phone record. If you would like the relationship to use a value other than id, you may pass a third argument to the hasOne method specifying your custom key:

class User extends Model {
  static entity = 'users'
  static fields () {
    return {
      id: this.attr(null),
      localId: this.attr(null),
      name: this.string(''),
      phone: this.hasOne(Phone, 'userId', 'localId')
    }
  }
}

Defining The Inverse Of The Relationship

So, we can access the Phone model from our User. Now, let's define a relationship on the Phone model that will let us access the User that owns the phone. We can define the inverse of a hasOne relationship using the belongsTo attribute:

class Phone extends Model {
  static entity = 'phones'
  static fields () {
    return {
      id: this.attr(null),
      userId: this.attr(null),
      number: this.string(''),
      user: this.belongsTo(User, 'userId')
    }
  }
}

In the example above, Pinia ORM will try to match the userId from the Phone model to an id on the User model.

If your parent model does not use id as its primary key, or you wish to join the child model to a different field, you may pass a third argument to the belongsTo method specifying your parent model's custom key:

class Phone extends Model {
  static entity = 'phones'
  static fields () {
    return {
      id: this.attr(null),
      number: this.string(''),
      user: this.belongsTo(User, 'userId', 'otherKey')
    }
  }
}