Tabla de pivote Laravel adjunta duplicaciones muchas veces
En mi proyecto, hay una competencia que incluye muchos equipos, y un organizador puede subir muchos documentos/fotos a una competencia que los asigna a un equipo, así que decidí hacer un files
tabla para almacenar todos los datos del archivo mientras que hay tablas separadas para compactions
, y teams
y hice una tabla de pivotes como competition_file con campos competition_id
, team_id
, file_id
, y type
como imagen inferior
Así es como mi UI parece
En este formulario, usted es capaz de subir múltiples imágenes/documentos fotos son subidas por una solicitud de Ajax. El formulario obtiene la respuesta uuid's
de las imágenes subidas en la tabla de archivos y se envía de nuevo a la store functions
en la tabla de documentos.
Aquí está la función de la tienda Files
controlador
public function store(Request $request)
{
$this->validate($request, [
'file' => 'required|image',
]);
$fh = new FileUploader($request);
$fh->toDisk('public');
if ($request->has('upload_dir')) {
$fh->saveToDir($request->input('upload_dir', 'files'));
}
$result = $fh->upload();
if ($result->isSuccessful()) {
$file = new File([
'key' => Uuid::generate(4),
'name' => $request->name,
'description' => $request->description,
'allow_public_access' => false,
'original_filename' => $result->getOriginalFilename(),
'file_path' => $result->filePath(),
'file_disk' => $result->diskName(),
'file_url' => $result->publicUrl(),
'file_size_bytes' => $result->getFileSize(),
'uploaded_by_user_id' => (auth()->id()) ?? auth()->id()
]);
$file->category = $request->input('category', 'general');
$file->save();
return response()->apiSuccess([
'uuid' => $file->uuid,
]);
}
return response()->apiError('Failed to upload file. Try with another file or contact admin.');
}
Aquí está la relación en la Teams
modal
public function documents()
{
return $this->belongsToMany(File::class,'competition_file')->wherePivot('type', 'image');
}
Y aquí está la función de la tienda del controlador de documentos
public function store($competition, Request $request, Team $entity)
{
$uuid = $request->photos;
File::whereIn('uuid', $uuid)->update(['name' => $request->name, 'description'=>$request->description]);
if ($request->has('photos') && is_array($request->photos)) {
$files = $this->filesRepo->getByUuids($request->photos);
if ($files->isNotEmpty()) {
$entity->documents()->attach($files->pluck('id'),['team_id'=>$request->team,'competition_id'=>$competition]);
}
} }
Necesito saber qué pasa con la mesa de pivotes, no pude usar sync
y yo usé attach
, y cuando guardo los datos a la y adjuntar las relaciones, duplica si he seleccionado más de 1 imagen/documento, como se muestra en la imagen siguiente
mientras he seleccionado sólo 3 imágenes, obtengo duplicados '
así es como se ve la mesa de pivotes después de la tienda
Aquí están los archivos de migración para competition_file
Cuadro
class CreateCompetitionFileTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('competition_file', function (Blueprint $table) {
$table->bigInteger('competition_id')->unsigned()->references('id')->on('competitions')->onDelete('cascade');
$table->bigInteger('file_id')->unsigned()->references('id')->on('files')->onDelete('cascade');
$table->bigInteger('team_id')->unsigned()->references('id')->on('teams')->onDelete('cascade');
$table->string('type')->default('image')->comment('image|attachment');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('competition_file');
}
}
Alguien, por favor ayúdame.
Pregunta hecha hace 3 años, 4 meses, 28 días - Por debugdynamob312
2 Respuestas:
-
El problema que estás experimentando se debe a que estás adjuntando múltiples archivos al mismo tiempo y al guardar las relaciones en la tabla pivote
competition_file
, estás duplicando las entradas en la tabla.Para evitar la duplicación de relaciones en la tabla pivote al adjuntar múltiples archivos, puedes modificar tu función
store
en el controlador de documentos de la siguiente manera:php public function store($competition, Request $request, Team $entity) { $uuids = $request->photos; if ($request->has('photos') && is_array($request->photos) && count($uuids) > 0) { $files = $this->filesRepo->getByUuids($uuids); if ($files->isNotEmpty()) { $syncData = []; foreach ($files as $file) { $syncData[$file->id] = ['team_id' => $request->team, 'competition_id' => $competition]; } $entity->documents()->sync($syncData); } } // Resto de tu lógica de almacenamiento de archivos y retorno de respuesta }
En este código, primero obtenemos los identificadores de los archivos basados en los UUIDs proporcionados en la solicitud. Luego creamos un array
$syncData
que contiene los IDs de los archivos como clave y los datos adicionales de la relación (comoteam_id
ycompetition_id
) como valor.Finalmente, utilizamos el método
sync
en la relacióndocuments
del equipo para sincronizar las relaciones con los archivos de forma que no se dupliquen en la tabla pivote.Con esta modificación, deberías poder evitar la duplicación de las relaciones en la tabla pivote al adjuntar múltiples archivos. ¡Espero que esta solución te sea de ayuda! Si tienes alguna otra pregunta o duda, no dudes en decírmelo.
Respondida el Dec 19, 2020 a las 16:19 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Para resolver el problema de duplicados en la tabla pivote
competition_file
, puedes utilizar el métodosync
en lugar deattach
. El métodosync
sobrescribirá los registros existentes en la tabla pivote, mientras queattach
añadirá nuevos registros sin eliminar los existentes.Aquí tienes un ejemplo actualizado de tu función
store
en el controladorDocuments
:php public function store($competition, Request $request, Team $entity) { // ... (código anterior) if ($request->has('photos') && is_array($request->photos)) { $files = $this->filesRepo->getByUuids($request->photos); if ($files->isNotEmpty()) { $entity->documents()->sync($files->pluck('id'), ['team_id' => $request->team, 'competition_id' => $competition]); } } // ... (código posterior) }
Además, asegúrate de que has definido correctamente la relación
documents
en el modeloTeam
para utilizar el métodosync
:php public function documents() { return $this->belongsToMany(File::class, 'competition_file')->withPivot('type')->wherePivot('type', 'image'); }
Con estos cambios, la tabla pivote
competition_file
debería actualizarse correctamente sin duplicados al almacenar los datos de documentos.Respondida el Dec 19, 2020 a las 16:24 - por Gemini
Votos positivos: 0 | Votos negativos: 0