¿Alguien puede ayudarme sobre cómo salvar la relación de muchos a muchos? Tengo tareas, el usuario puede tener muchas tareas y la tarea puede tener muchos usuarios (de muchos a muchos). Lo que quiero lograr es que en el formulario de actualización el administrador pueda asignar múltiples usuarios a una tarea específica. Esto se hace a través de la entrada de selección múltiple html
name="taskParticipants[]"
El problema aquí es que a través del mismo formulario (entrada) puede agregar / eliminar usuarios, por eso 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 las tablas id de tareas | título | fecha límite
user_tasks
id|task_id|user_id
laravel
laravel-4
eloquent
relationship
SuperManSL
fuente
fuente
$workers = Input::get('taskParticipants'); $task->taskParticipants()->sync($workers);
y eso es todo lo que necesita, siempre que pase de ese formulario a todos los usuarios, asignados a la tarea.Respuestas:
tldr; Usar
sync
con 2do parámetrofalse
La relación de varios a varios está
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
osync
.La diferencia entre los dos es:
1
attach
agregará una nueva fila en la tabla dinámica sin verificar si ya está allí. Es bueno cuando tiene datos adicionales vinculados a esa relación, por ejemplo:User
yExam
vinculado con la tabla dinámicaattempts: 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]
2,
sync
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 Y 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]
fuente
$this->belongsToMany('User')
si usa el nombre de la tabla alfabéticamente y en singular (entask_user
lugar deuser_tasks
)sync
, no se preocupe. Sugiero usar el segundo parámetro establecido en falso siempre que desee 'agregar una nueva tarea para un usuario' o 'asignar un usuario a una tarea', cuando pase solo unoid
de los modelos relacionados.sync
devuelve una matriz condetached
,attached
yupdated
listas.attach
no devuelve nada, pero en ambos casos obtendría una excepción si sucediera algo inesperado en las llamadas a la base de datos.Aquí están mis notas sobre cómo guardar y actualizar todas las relaciones de Eloquent.
en uno a uno :
Tienes que usar HasOne en el primer modelo y BelongsTo en el segundo modelo
para agregar un registro en el primer modelo ( HasOne ) use la función de guardar
ejemplo:
$post->comments()->save($comment);
para agregar un registro en el segundo modelo ( Pertenece a ) use la función asociada
ejemplo:
$user->account()->associate($account); $user->save();
en uno a muchos :
Tienes que usar HasMany en el primer modelo y BelongsTo en el segundo modelo
para agregar un registro en la primera tabla ( HasMany ) use las funciones save o saveMany
ejemplo:
$post->comments()->saveMany($comments);
para agregar un registro en el segundo modelo ( Pertenece a ) use la función asociada
ejemplo:
$user->account()->associate($account); $user->save();
de 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 adjuntar o sincronizar
Ambas funciones aceptan un solo ID o una matriz de ID
la diferencia es adjuntar verificaciones si el registro ya existe en la tabla dinámica mientras que la sincronización no
ejemplo:
$user->roles()->attach($roleId);
en polimórfico uno a muchos :
Tienes que usar MorphMany en el modelo principal y MorphTo en todos los modelos (*** capaces)
para agregar registros en todos los demás modelos, use el comando guardar
ejemplo:
$course->tags()->save($tag);
la tabla dinámica debe tener las siguientes columnas:
. ID del modelo principal
. (*** capaz) ID
. (*** capaz) Tipo
en polimórficos muchos a muchos :
Tienes que usar MorphByMany en el modelo principal y MorphToMany en todos los modelos (*** capaces)
para agregar registros en todos los demás modelos, use save o saveMany
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
. (*** capaz) 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, existe una solución sencilla y agradable para eso.
Aquí hay un artículo que escribí, inspirado en esta respuesta. Importante comprobarlo: https://hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209
fuente
updateMany
como ese? graciassyncWithoutDetaching([$id_one, $id_two, $id_three]);
es lo que estas buscando. ¡Realmente hace exactamente lo que hace [sync
con el segundo parámetrofalse
]!fuente
La
sync
función borra las relaciones existentes y convierte su matriz en la lista completa de relaciones. En suattach
lugar, desea agregar relaciones sin eliminar otras.fuente