es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Laravel/Inertia: llamando una clave primaria desde una clave foránea de una clave foránea.

Actualmente estoy utilizando Laravel, Inertiajs y Vuejs para crear un blog, y necesito ayuda con la lógica para obtener el nombre de usuario.

Tengo 3 tablas:

Usuarios:

  • id (pk)
  • name

Blogs:

  • id (pk)
  • user_id (clave foránea)

Comentarios:

  • id (pk)
  • blog_id (clave foránea)
  • user_id (clave foránea)

Tengo una página de blog, que está anidada dentro de una ruta dinámica desde web.php:

Route::get('/blogs/{id}', [BlogController::class, 'show'])->name("blogs.show");

La página del blog contiene una publicación de blog y una sección de comentarios, que es llamada por un BlogController:

public function show(Blog $id)
{
    $user = User::find($id->user_id)->name;

    return Inertia::render('Components/Blog', [
        'blog' => [
            'id' => $id->id,
            'name' => $user,
            'title' => $id->title,
            'body' => $id->body,
            'created_at' => $id->created_at,
            'updated_at' => $id->updated_at,
            'comments' => $id->blogComments()->orderByDate()->get()->all(),
        ],
    ]);
}

En cuanto a obtener el nombre de usuario del blogger, funciona perfectamente en $user = User::find($id->user_id)->name; y se llama de vuelta desde el componente Vue como una propiedad de blog: <p>{{ blog.name }}</p>. Ahora, lo que quiero es llamar el nombre de usuario también en la sección de comentarios (ver Objetivo a continuación).

La sección de comentarios anterior es llamada desde el método show() en BlogController:

<template>
  <div>
    <div v-for="comment in blog.comments" :key="comment.id" class="hover:bg-gray-100 focus-within:bg-gray-100">
      <p>comment id: {{ comment.id }}</p>
      <p>comment body: {{ comment.body }}</p>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    blog: Object,
  },
};
</script>

Pero mi problema es que no logro entender la lógica para obtener el nombre de usuario de la tabla Usuarios dentro del método show(). Hasta ahora, hay una relación uno a muchos desde la tabla Blogs a la tabla Comments, llamando la clave foránea en la tabla Comments a la clave principal en la tabla Blogs en el controlador: 'comments' => $id->blogComments()->orderByDate()->get()->all(),

Entonces, ¿cómo agrego otra capa en esto llamando la clave foránea en la tabla Comments (dentro de un BlogController) a la clave principal en la tabla Usuarios?

He estado en esto durante varias horas y estoy seguro de que me falta algo simple, así que agradecería si hay un par de ojos frescos que miren esto.

Gracias.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para obtener el nombre de usuario de la tabla Users en la sección de comentarios, puedes agregar un método en el modelo Blog para definir una relación entre las tablas Comments y Users. Puedes hacer esto agregando una relación belongsTo en el modelo Comment:

    class Comment extends Model
    {
        public function user()
        {
            return $this->belongsTo(User::class);
        }
    }
    

    Luego, en el método show() del controlador BlogController, puedes cargar de forma ansiosa (eager load) la relación user de los comments utilizando el método with():

    public function show(Blog $id)
    {
        $blog = $id->load('blogComments.user');
    
        return Inertia::render('Components/Blog', [
            'blog' => $blog,
        ]);
    }
    

    Ahora, en el componente Vue, puedes acceder al nombre de usuario del autor del comentario usando comment.user.name de esta manera:

    <template>
      <div>
        <div v-for="comment in blog.comments" :key="comment.id" class="hover:bg-gray-100 focus-within:bg-gray-100">
          comment id: {{ comment.id }}
          comment body: {{ comment.body }}
          <p>comment by: {{ comment.user.name }}</p> <!-- nueva línea -->
        </div>
      </div>
    </template>
    

    Esto debería darte el nombre de usuario del autor del comentario en la sección de comentarios.

Comments are closed.