Skip to content

HasOne Relationship

The HasOne relationship represents a one-to-one relationship where the foreign model stores a reference to the current model.

Explanation

For example, a User has one Profile:

Defining the Relationship

The relationship is defined in your model configuration under the relationships property as a tuple:

typescript
[HasOne, foreignModelTable: string, foreignKey: string, originatingPrimaryKey?: string, foreignPrimaryKey?: string]

Required Parameters

  • HasOne: The relationship type
  • foreignModelTable: The table name of the related model
  • foreignKey: The foreign key in the related model that references the current model

Optional Parameters

  • originatingPrimaryKey: The primary key in the current model (defaults to 'id')
  • foreignPrimaryKey: The primary key in the foreign model (defaults to 'id')

Example

typescript
{
  models: {
    users: {
      schema: '++id, email, createdAt, updatedAt',
      properties: ['id', 'email', 'password'],
      primaryKey: 'id',
      relationships: {
        profile: [HasOne, 'profiles', 'user_id'], 
      }
    },
    profiles: {
      schema: '++id, user_id, full_name, avatar_url', 
      properties: ['id', 'user_id', 'full_name', 'avatar_url'],
    }
  }
}

In this example:

  • The Profile model has a user_id foreign key that references the User model's id
  • The relationship is defined as [HasOne, 'profiles', 'user_id'] where:
    • 'profiles' is the foreignModelTable
    • 'user_id' is the foreignKey
    • The primary keys default to 'id' since they're not specified

Accessing the Relationship

typescript
// Get the user's profile
const user = await User.find(1)
const profile = await user.profile 

// The relationship is reactive
user.profile.onChange((newProfile) => { 
  console.log('Profile updated:', newProfile)
})

// You can also eager load the relationship
const users = await User.query()
  .with('profile') 
  .fetch()