Tengo comentarios y respuestas a esos comentarios y quiero traer las relaciones completas. Quiero traer todas las relaciones de comentarios al llamar a las respuestas. Es un poco confuso, así que permítanme mostrar que quiero decir con datos reales.

Este es el modelo

class ForumReply extends Model
{
    protected $fillable = [
        'user_id',
        'bulletin_id',
        'comment',
        'anonymous'
    ];

    public $timestamps = true;

    public function discussionForum()
    {
        return $this->belongsTo(DiscussionForum::class);
    }

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

    public function replies()
    {
        return $this->hasMany(ForumReply::class, 'parent_id');
    }
}

Esta es la función en el controlador

public function show($id)
{
    $forum = DiscussionForum::findOrFail($id)
        ->with('comments', 'user')->first();
    $comment = ForumReply::with('discussionForum', 'user', 'replies')
        ->where('discussion_forum_id', $forum->id)
        ->orderByDesc('comment_time')->get();

    return Inertia::render('Forum/View.vue', [
        'forum' => $forum,
        'comments' => $comment
    ]);
}

Estos son los datos que obtengo para la consulta $comment, ya que puede ver que la parte de respuestas tiene muy poca información, para poder mostrarla como quiero necesito más información, como la información de usuario de la persona quien respondió no solo la persona con el comentario de los padres.

{ 
   "id":4,
   "user_id":41,
   "discussion_forum_id":1,
   "parent_id":null,
   "comment":"adsfasdf asdf asdfa sdf ",
   "comment_time":"2019-12-03 11:25:00",
   "created_at":null,
   "updated_at":null,
   "discussion_forum":{ 
      "id":1,
      "theme":"asdfa",
      "description":"asdffghjluui",
      "user_id":1,
      "anonymous":0,
      "start_date":"2019-11-24 06:00:00",
      "end_date":"2019-12-30 06:00:00",
      "created_at":"2019-11-27 13:21:03",
      "updated_at":"2019-11-27 13:21:03"
   },
   "user":{ 
      "id":41,
      "name":"Isadora Felix",
      "card":"12346",
      "scard":"97531",
      "user_type_id":4,
      "email":"i@email.com",
      "created_at":"2019-12-03 10:09:26",
      "updated_at":"2019-12-03 10:09:26"
   },
   "replies":[ 
      { 
         "id":6,
         "user_id":39,
         "discussion_forum_id":1,
         "parent_id":4,
         "comment":"not agreeing",
         "comment_time":"2019-12-03 11:26:01",
         "created_at":null,
         "updated_at":null
      }
   ]
}

¿Hay otra forma de traer esta información de manera que pueda obtener la información en la respuesta como si fuera un comentario de los padres? ¿O hay una mejor manera de abordar esto?

0
Nancy 4 dic. 2019 a las 00:16

2 respuestas

La mejor respuesta

Puede cargar relaciones anidadas con la notación de puntos. Por ejemplo:

$forum = DiscussionForum::with(['user', 'comment' => function ($query) {
    return $query->orderByDesc('comment_time');
}, 'comment.user', 'comments.replies.user'])->findOrFail($id);

Este código cargará el foro de discusión con el usuario y los comentarios con sus autores. Luego, para cada comentario, también recupera sus respuestas con sus respectivos autores.

Nota al margen : tenga en cuenta que findOrFail($id) realmente ejecuta una consulta. Si luego llama a ->with(...)->first(), está realizando una segunda consulta en la base de datos. En su lugar, puede comenzar con el método ::with(...) y luego llamar a ->findOrFail($id).

1
mdexp 3 dic. 2019 a las 21:36

Si sabe que nunca querrá acceder al ForumReply sin su usuario, puede agregar el usuario al atributo protegido "con" para que siempre se agregue con cada modelo de este tipo

class ForumReply extends Model
{
   protected $with = ['user'];
}

Esto le ahorrará el código para incluir al usuario y también lo ayudará con la siguiente parte

A menos que limite las respuestas del foro a una sola respuesta, deberá considerar el nivel de anidamiento en la relación. Sin embargo, hay una solución fácil para esto, hacer que su relación sea recursiva.

public function replies()
{
  return $this->hasMany(ForumReply::class, 'parent_id')->with('replies');
}

La combinación de esos dos cambios cargará todas las respuestas a una respuesta, incluso si están respondiendo a otra respuesta, y adjuntará el usuario a cada una.

1
Alec Joy 3 dic. 2019 a las 21:41