relacionadas - laravel relaciones muchos a muchos
Laravel guarda/actualiza muchas a muchas relaciones (3)
Aquí están mis notas sobre cómo guardar y actualizar todas las relaciones Eloquentes.
en uno a uno :
Tienes que usar HasOne en el primer modelo y BelongsTo en el segundo modelo
para agregar registro en el primer modelo ( HasOne ) use la función guardar
ejemplo: $post->comments()->save($comment);
para agregar registro en el segundo modelo ( BelongsTo ) use la función asociada
ejemplo: $user->account()->associate($account); $user->save();
$user->account()->associate($account); $user->save();
de uno a muchos :
Tienes que usar HasMany en el primer modelo y BelongsTo en el segundo modelo
para agregar registro en la primera tabla ( HasMany ) use las funciones guardar o guardarMany
ejemplo: $post->comments()->saveMany($comments);
para agregar registro en el segundo modelo ( BelongsTo ) use la función asociada
ejemplo: $user->account()->associate($account); $user->save();
$user->account()->associate($account); $user->save();
en muchos a muchos :
Tienes que usar BelongsToMany en el primer modelo y BelongsToMany en el segundo modelo
para agregar registros en la tabla dinámica use las funciones de adjuntar o sincronizar
Ambas funciones aceptan una sola ID o una matriz de ID
la diferencia es adjuntar cheques si el registro ya existe en la tabla dinámica, mientras que la sincronización no
ejemplo: $user->roles()->attach($roleId);
en uno polimórfico a muchos :
Tienes que usar MorphMany en el modelo principal y MorphTo en todos los modelos (*** able)
para agregar registros en todos los otros modelos use la opción guardar
ejemplo: $course->tags()->save($tag);
la tabla dinámica debe tener las siguientes columnas:
. ID del modelo principal
. (*** capaz) ID
. (*** able) Tipo
en muchos polimórficos a muchos :
Tienes que usar MorphByMany en el modelo principal y MorphToMany en todos los modelos (*** able)
para agregar registros en todos los otros modelos use guardar o guardarMany
ejemplo: $course->tags()->save($tag);
ejemplo: $course->tags()->saveMany([$tag_1, $tag_2, $tag_3]);
la tabla dinámica debe tener las siguientes columnas:
. ID del modelo principal
. (*** capaz) ID
. (*** able) Tipo
en Has Many Through (atajo):
Tienes que usar HasManyThrough en la primera tabla y tener las relaciones normales en las otras 2 tablas
esto no funciona para las relaciones ManyToMany (donde hay una tabla dinámica)
sin embargo, hay una buena y sencilla solución solo para eso.
Aquí hay un artículo que escribí, inspirado por esta respuesta. Importante comprobarlo: https://hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209
¿Alguien puede ayudarme a cómo salvar una relación de muchos a muchos? Tengo tareas, el usuario puede tener muchas tareas y la tarea puede tener muchos usuarios (muchos para muchos), lo que quiero lograr es que en forma de actualización el administrador pueda asignar múltiples usuarios a tareas específicas. Esto se hace a través de la entrada de selección múltiple html
name="taskParticipants[]"
La clave aquí es que a través del mismo formulario (entrada) puede agregar / eliminar usuarios, es por eso que tengo que usar Sync (). Tal vez debería empezar desde el principio, pero no sé por dónde empezar ...
Este es mi modelo de Usuario:
public function tasks()
{
return $this->belongsToMany(''Task'',''user_tasks'');
}
Modelo de tarea
public function taskParticipants()
{
return $this->belongsToMany(''User'',''user_tasks'');
}
TaskController
public function update($task_id)
{
if (Input::has(''taskParticipants''))
{
foreach(Input::get(''taskParticipants'') as $worker)
{
$task2 = $task->taskParticipants->toArray();
$task2 = array_add($task2,$task_id,$worker);
$task->taskParticipants()->sync(array($task2));
}
}
}
Esta es la estructura de tablas tareas id | título | fecha límite
user_tasks
id|task_id|user_id
La función de sync
borra las relaciones salientes y hace que su matriz sea la lista completa de relaciones. Desea attach
lugar para agregar relaciones sin eliminar otras.
tldr; Usa la sync
con el 2do parametro false
La relación de muchos a muchos es belongsToMany
en ambos modelos:
// Task model
public function users()
{
return $this->belongsToMany(''User'', ''user_tasks''); // assuming user_id and task_id as fk
}
// User model
public function tasks()
{
return $this->belongsToMany(''Task'', ''user_tasks'');
}
Para agregar una nueva relación use attach
o sync
.
La diferencia entre los dos es:
1 attach
agregará una nueva fila en la tabla pivote sin verificar si ya está allí. Es bueno cuando tiene datos adicionales vinculados a esa relación, por ejemplo:
User
y Exam
vinculados con attempts: id, user_id, exam_id, score
tabla dinámica attempts: id, user_id, exam_id, score
Supongo que esto no es lo que necesitas en tu situación:
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6]
$user->tasks()->attach([5,6,7]);
// then
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6,5,6,7]
sync
2, por otro lado, eliminará todas las relaciones y las configurará de nuevo:
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6]
$user->tasks()->sync([1,2,3]);
// then
$user->tasks()->getRelatedIds(); // [1,2,3]
o configurará nuevas relaciones sin separar el AND anterior sin agregar duplicados:
$user->tasks()->sync([5,6,7,8], false); // 2nd param = detach
// then
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6,7,8]