Understanding One-to-One Relations with Prisma ORM
Tags: prisma, javascriptlibraries, softwaredevelopment
Published: 2024-06-15 18:36:49

Prisma ORM is a powerful tool for managing databases in Node.js and TypeScript projects. One of its most important features is the ability to define relationships between tables, including One-to-One (one-to-one) relationships. In this post, we will explore how to set up and work with One-to-One relationships in Prisma ORM.

## What is a One-to-One Relationship?

In a database, a One-to-One relationship means that a record in one table is directly associated with a single record in another table. For example, let's say you have two tables: `User` and `Profile`. Each `User` has a single `Profile` and each `Profile` belongs to a single `User`.

## Setting Up a One-to-One Relationship in Prisma

Let's see how to define a One-to-One relationship between two tables using Prisma ORM. For this example, we will create the `User` and `Profile` tables.

### Step 1: Initial Setup

First, make sure you have Prisma installed in your project:

```bash
npm install @prisma/client
npx prisma init
```

This will create a `prisma` directory containing the `schema.prisma` file where we will define our data model.

### Step 2: Defining the Models

Open the `schema.prisma` file and define the `User` and `Profile` models:

```prisma
model User {
  id      Int     @id @default(autoincrement())
  email   String  @unique
  name    String?
  profile Profile?

  @@map("users")
}

model Profile {
  id     Int    @id @default(autoincrement())
  bio    String
  userId Int    @unique
  user   User   @relation(fields: [userId], references: [id])

  @@map("profiles")
}
```

Here, we define two models:

- `User`: Represents a user with a unique ID, a unique email, an optional name, and an optional profile.
- `Profile`: Represents a profile with a unique ID, a bio, and a `userId` field that is a foreign key referencing the `id` of the `User`.

### Step 3: Migrating the Database

After defining the models, we need to migrate the database to reflect these changes:

```bash
npx prisma migrate dev --name init
```

This will create the `users` and `profiles` tables in your database with the One-to-One relationship configured.

## Working with One-to-One Relationships

Now that we have our models defined and migrated, let's see how to create, read, and manipulate data with this relationship.

### Creating a User and a Profile

```typescript
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

async function main() {
  const user = await prisma.user.create({
    data: {
      email: 'alice@prisma.io',
      name: 'Alice',
      profile: {
        create: {
          bio: 'Software Developer',
        },
      },
    },
  });

  console.log(user);
}

main()
  .catch((e) => {
    throw e;
  })
  .finally(async () => {
    await prisma.$disconnect();
  });
```

In this example, we are creating a `User` with an associated `Profile` in a single operation.

### Reading Related Data

To fetch a user along with their profile, we use the `include` operation:

```typescript
const userWithProfile = await prisma.user.findUnique({
  where: {
    email: 'alice@prisma.io',
  },
  include: {
    profile: true,
  },
});

console.log(userWithProfile);
```

### Updating a Profile

To update the profile of an existing user:

```typescript
const updatedProfile = await prisma.profile.update({
  where: {
    userId: userWithProfile.id,
  },
  data: {
    bio: 'Full Stack Developer',
  },
});

console.log(updatedProfile);
```

## Conclusion

Defining and working with One-to-One relationships in Prisma ORM is straightforward and intuitive. With the correct configuration in the `schema.prisma` file and using the methods provided by Prisma Client, you can easily manage and interact with related data in your database.

Prisma not only simplifies the process of defining relationships but also provides a powerful API for working with this data, making application development more efficient and productive.