00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Enum e Tipi Composti

Enum

Gli enum permettono di definire un insieme fisso di valori possibili per un campo. Sono supportati nativamente da PostgreSQL, MySQL e MongoDB.

Definire un Enum

enum Role {
  USER
  ADMIN
  MODERATOR
  EDITOR
}

enum OrderStatus {
  PENDING
  PROCESSING
  SHIPPED
  DELIVERED
  CANCELLED
}

model User {
  id   Int    @id @default(autoincrement())
  name String
  role Role   @default(USER)
}

model Order {
  id     Int         @id @default(autoincrement())
  total  Decimal
  status OrderStatus @default(PENDING)
}

Usare gli Enum nelle Query

// Creare un utente admin
const admin = await prisma.user.create({
  data: {
    name: 'Marco',
    role: 'ADMIN',
  },
})

// Filtrare per ruolo
const moderators = await prisma.user.findMany({
  where: {
    role: 'MODERATOR',
  },
})

// Filtrare con operatore IN
const staff = await prisma.user.findMany({
  where: {
    role: {
      in: ['ADMIN', 'MODERATOR', 'EDITOR'],
    },
  },
})

// Aggiornare lo stato di un ordine
const order = await prisma.order.update({
  where: { id: 1 },
  data: {
    status: 'SHIPPED',
  },
})

Enum con TypeScript

Prisma genera automaticamente i tipi TypeScript per gli enum:

import { Role, OrderStatus } from '@prisma/client'

function isPrivileged(role: Role): boolean {
  return role === Role.ADMIN || role === Role.MODERATOR
}

function canCancel(status: OrderStatus): boolean {
  return status === OrderStatus.PENDING || status === OrderStatus.PROCESSING
}

Mappare i Valori Enum

Puoi mappare i valori dell’enum a valori diversi nel database:

enum Color {
  RED   @map("rosso")
  GREEN @map("verde")
  BLUE  @map("blu")

  @@map("colori")
}

Tipi Composti (MongoDB)

I tipi composti (composite types) sono disponibili solo con MongoDB. Permettono di definire oggetti embedded direttamente nel documento.

Definire un Tipo Composto

// Usa "type" invece di "model" per i tipi composti
type Address {
  street  String
  city    String
  zip     String
  country String
}

type SocialMedia {
  platform String
  url      String
  username String?
}

model User {
  id      String        @id @default(auto()) @map("_id") @db.ObjectId
  name    String
  address Address       // Oggetto embedded singolo
  socials SocialMedia[] // Array di oggetti embedded
}

Operazioni con Tipi Composti

// Creare un utente con indirizzo e social
const user = await prisma.user.create({
  data: {
    name: 'Giulia',
    address: {
      street: 'Via Roma 1',
      city: 'Milano',
      zip: '20100',
      country: 'Italia',
    },
    socials: [
      { platform: 'GitHub', url: 'https://github.com/giulia', username: 'giulia' },
      { platform: 'Twitter', url: 'https://twitter.com/giulia' },
    ],
  },
})

// Filtrare per campo nested
const milanUsers = await prisma.user.findMany({
  where: {
    address: {
      is: {
        city: 'Milano',
      },
    },
  },
})

// Aggiornare l'indirizzo
const updated = await prisma.user.update({
  where: { id: user.id },
  data: {
    address: {
      update: {
        city: 'Roma',
        zip: '00100',
      },
    },
  },
})

Tipi Composti Opzionali e Nested

type ContactInfo {
  email   String
  phone   String?
  address Address?  // Tipo composto nested opzionale
}

type Address {
  street String
  city   String
  zip    String
}

model Company {
  id      String      @id @default(auto()) @map("_id") @db.ObjectId
  name    String
  contact ContactInfo
}

JSON come Alternativa (SQL)

Per i database SQL, se hai bisogno di dati strutturati ma flessibili, puoi usare il tipo Json:

model Product {
  id         Int    @id @default(autoincrement())
  name       String
  attributes Json   // Dati strutturati flessibili
  metadata   Json?
}
// Creare un prodotto con attributi JSON
const product = await prisma.product.create({
  data: {
    name: 'Laptop Pro',
    attributes: {
      color: 'silver',
      ram: 16,
      storage: { type: 'SSD', size: 512 },
      ports: ['USB-C', 'HDMI', 'Thunderbolt'],
    },
  },
})

// Filtrare per campo JSON (PostgreSQL)
const products = await prisma.product.findMany({
  where: {
    attributes: {
      path: ['color'],
      equals: 'silver',
    },
  },
})

Il tipo Json e’ flessibile ma non ha validazione a livello di schema. Per dati fortemente tipizzati, preferisci modelli relazionali separati o tipi composti con MongoDB.