tabla dinámica de laravel con clave externa anulable
Pregunta
Tengo una tabla dinámica configurada de la siguiente manera:
user_roles
user_id //fk->users.id
assoc_id //nullable fk->association.id
role //varchar
Configuré mi base de datos de esta manera porque los roles representan una relación de muchos a muchos:una asociación tiene muchos usuarios y un usuario puede estar en muchas asociaciones.cada usuario tiene un rol dentro de una asociación.
Sin embargo, existen algunos roles que pueden existir fuera de una asociación.La base de datos está configurada para aceptar un valor nulo en el assoc_id
campo y puedo insertar uno manualmente desde la línea de comando, pero cuando intento ejecutar
$user->roles()->attach(NULL, "outside contractor");
en mi archivo semilla, aparece un error que dice
[Illuminate\Database\QueryException]
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update
a child row: a foreign key constraint fails (`database`.`user_roles`, CONSTR
AINT `user_roles_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users
` (`id`)) (SQL: insert into `user_roles` () values ())
Esto es particularmente confuso porque ¿no debería el primer argumento aquí referirse a la assoc_id
?Cuando reemplazo el NULL
con un valido assoc_id
,
$user->roles()->attach(1, "outside contractor");
la inserción funciona bien y el primer argumento se refiere a la assoc_id
en la mesa.
¿Qué está pasando mal?
Solución
Si no proporciona una clave o claves para attach
/sync
, Eloquent no insertará nada.Es un comportamiento bastante esperado, ya que lo que estás intentando hacer es:
Crear un vínculo entre X y nulo
esto no es lo que se supone que debe hacer ORM.
En su lugar, inserte esas filas manualmente:
$data = [
'user_id' => 99,
'assoc_id' => null,
'role' => 'outside contractor'
];
DB::table('user_roles')->insert($data);