Relaciones y herencia de modelos
Conecta tus modelos con @Relationship, controla el borrado en cascada, y aprovecha la herencia de modelos, la gran novedad de SwiftData en 2026.
Los datos reales no viven aislados: un proyecto tiene tareas, un usuario tiene pedidos, un álbum tiene fotos. SwiftData modela esas conexiones con @Relationship, y en 2026 suma algo muy pedido: la herencia de modelos.
- Definir relaciones uno-a-muchos con
@Relationship. - Controlar qué pasa al borrar (delete rules).
- Relaciones inversas.
- Herencia de modelos (novedad 2026).
Relaciones uno-a-muchos
Una relación es solo una propiedad que apunta a otro modelo (o a un array de ellos):
@Model
class Proyecto {
var nombre: String
@Relationship(deleteRule: .cascade) var tareas: [Tarea] = []
init(nombre: String) { self.nombre = nombre }
}
@Model
class Tarea {
var titulo: String
var proyecto: Proyecto? // el lado "muchos-a-uno"
init(titulo: String) { self.titulo = titulo }
}
Añadir es tan simple como manipular el array: proyecto.tareas.append(tarea). SwiftData mantiene la conexión en la base de datos.
Delete rules: qué pasa al borrar
deleteRule controla el efecto de borrar el padre sobre los hijos:
.cascade
Borra los hijos también. Borrar un proyecto borra sus tareas. El más común.
.deny
Impide borrar el padre si tiene hijos. Protege contra borrados accidentales.
.nullify
Deja los hijos, pero rompe la relación (pone la referencia a nil). Por defecto.
.cascade para composición fuerte (una tarea no tiene sentido sin su proyecto). .nullify cuando el hijo sobrevive por su cuenta (borrar una etiqueta no debería borrar los artículos etiquetados, solo quitarles la etiqueta). Pensar esto al modelar te ahorra datos huérfanos o borrados en cadena inesperados.
Herencia de modelos (novedad 2026)
La función más pedida y que por fin llegó este año: un @Model puede heredar de otro. Útil cuando varios tipos comparten campos comunes:
@Model
class Elemento {
var titulo: String
var creado: Date
init(titulo: String) { self.titulo = titulo; self.creado = .now }
}
@Model
class Nota: Elemento {
var contenido: String = ""
}
@Model
class Recordatorio: Elemento {
var fecha: Date = .now
var completado = false
}
Ahora puedes consultar todos los Elemento (y obtener notas y recordatorios juntos) o cada subtipo por separado. Comparten los campos base sin duplicarlos.
La herencia de modelos te deja expresar jerarquías naturales de tu dominio (“todo es un Elemento con título y fecha, pero unos son notas y otros recordatorios”) directamente en el almacén, sin trucos ni tablas duplicadas. Combínalo con lo del Nivel 1: aquí las clases y la herencia sí tienen su lugar, porque estás modelando entidades persistentes con identidad. SwiftData 2026 hace que la capa de datos se parezca cada vez más a cómo piensas el problema, no a cómo lo guarda SQLite.
- Crea un
Proyectocon una relación@Relationship(deleteRule: .cascade)a[Tarea]. - Añade tareas a un proyecto con
.appendy muéstralas. - Borra el proyecto y comprueba que sus tareas también desaparecen (cascade).
- Crea un modelo base
Elementoy dos subclases que hereden de él. - Consulta todos los
Elementoy observa que trae ambos subtipos.