Problema al utilizar la función "pluck" en Laravel con relaciones polimórficas

Publicado por Lynn
hace 5 meses

Mi problema es que estoy intentando utilizar la función "pluck" en Laravel para obtener un array con los valores de una columna específica de una relación polimórfica.

Tengo tres tablas en mi base de datos: "posts", "comments" y "likes". La tabla "posts" tiene una relación polimórfica con las tablas "comments" y "likes". Aquí está mi código:

En la clase "Post":

public function likes()
{
    return $this->morphMany(Like::class, 'likeable');
}

public function comments()
{
    return $this->morphMany(Comment::class, 'commentable');
}

En la clase "Like":

public function likeable()
{
    return $this->morphTo();
}

En la clase "Comment":

public function commentable()
{
    return $this->morphTo();
}

Ahora quiero obtener un array con los valores de la columna "user_id" de los likes. Intenté utilizar la función "pluck" de la siguiente manera:

$post = Post::find(1);
$likesUserId = $post->likes->pluck('user_id')->toArray();

Pero obtengo el siguiente error:

Call to undefined method Illuminate\\Database\\Eloquent\\Collection::pluck()

¿Cómo puedo solucionar este error y obtener el array con los valores de la columna "user_id" de los likes correctamente? Gracias de antemano por su ayuda.

Laravel pluck relaciones polimórficas
Respuesta de Gordon Shumway
hace 5 meses

¡Hola Lynn!

El error que estás enfrentando se debe a que estás intentando usar el método pluck en una instancia de Eloquent\Collection que aún no ha sido cargada. Si intentas hacer un pluck directamente sobre la relación, Laravel intentará llamar a pluck en la relación en lugar de en la colección de resultados.

Podrías hacer uso de la carga diferida (lazy loading) para solucionar esto. Sin embargo, dado que eso podría producir múltiples consultas a la base de datos si no estás trabajando con una instancia cargada, una mejor solución es utilizar el método with para cargar la relación y después aplicar el pluck sobre la colección de resultados.

Aquí tienes cómo podrías hacerlo:

$post = Post::with('likes')->find(1);

// Asegúrate de que $post no es null
if ($post) {
    $likesUserId = $post->likes->pluck('user_id')->toArray();
} else {
    // Manejo del caso en el que no se encuentra el Post
    $likesUserId = [];
}

// Ahora $likesUserId tiene los user_id que buscabas

O también podrías utilizar el método load si ya tienes la instancia del modelo Post pero la relación no ha sido cargada todavía:

$post = Post::find(1);

// Asegúrate de que $post no es null
if ($post) {
    $post->load('likes');
    $likesUserId = $post->likes->pluck('user_id')->toArray();
} else {
    // Manejo del caso en el que no se encuentra el Post
    $likesUserId = [];
}

// Continúa con el proceso

Utilizar with o load asegurará que la relación se carga correctamente antes de intentar pluckear los valores. De esta manera, evitarás el error que estás viendo.

Espero que esto resuelva tu problema. ¡Suerte con tu código!