Obtener campos específicos en una relación hasMany

3 minutos de lectura

Avatar de usuario de Tony
tonio

tengo un tiene muchos función de relación como esta:

public function articles()
{
    return $this->hasMany('App\Article');
}

Y utilízalo así:

$data = \App\User::with('articles')->get();

No tengo ningún problema con él, ya que está devolviendo los datos esperados. Algo como esto:

{
"id": 1,
"name": "Jhon",
"lastname": "Doe",
"articles": [
    {
        "id": 1,
        "title": "Article 1",
        "status": "published",
        "published_at": "2015-04-30"
    },
    {
        "id": 2,
        "title": "Article 2",
        "status": "draft",
        "published_at": null
    }
 ]
}

Lo que estoy tratando de lograr, pero todavía no puedo, es obtener solo un subconjunto de los campos de la relación para obtener esto:

{
"id": 1,
"name": "Jhon",
"lastname": "Doe",
"articles": [
    {
        "id": 1,
        "title": "Article 1"
    },
    {
        "id": 2,
        "title": "Article 2"
    }
  ]
}

Mi intención es encontrar una manera de especificar el subconjunto de campos en la función del Modelo en lugar de iterar la colección que regresa y desarmar los campos no deseados.

es posible?

avatar de usuario de patricus
patricio

Si es posible. Tienes un par de opciones.

*nótese bien: Para las opciones 1 y 2 a continuación, la clave externa (user_id) debe seleccionarse para que Laravel sepa cómo vincular los modelos al construir las relaciones.

  1. Modifique la consulta de relación cuando la use. Él with() El método puede aceptar una matriz de pares clave/valor donde la clave es el nombre de la relación y el valor es un cierre que modifica la consulta de la relación.

     $data = \App\User::with(['articles' => function($query) {
         // user_id is required here*
         $query->select(['id', 'title', 'user_id']);
     }])->get();
    
  2. Cree una nueva relación que contenga los campos que desee.

     public function articleTitles() {
         // user_id is required here*
         return $this->hasMany('App\Article')->select(['id', 'title', 'user_id']);
     }
    
     $data = \App\User::with('articleTitles')->get();
    
  3. Si solo le preocupa la salida de matriz/json, puede modificar el modelo App\Article para mostrar solo la identificación y el título cuando se convierte en una matriz.

     class Article extends Model {
         protected $visible = ['id', 'title'];
     }
    

Lo que elijas depende de lo que necesites.

  • Previamente había probado la opción 2 sin éxito porque devolvía vacío en “artículos”. Hoy probé la opción 1 y también volví vacío en “artículos”. Probé $consulta->orderBy(‘id’, ‘asc’); y funciona pero con el método “seleccionar” no funciona.

    – Tony

    4 mayo 2015 a las 11:31

  • @Tony Al usar las opciones 1 o 2, debe asegurarse de haber incluido la clave externa en la declaración de selección (‘id’), de lo contrario, Laravel no sabrá cómo vincular los objetos y el atributo de sus artículos siempre será vacío.

    – patricio

    4 mayo 2015 a las 19:01

  • ¡Esa fue la pieza que hizo que funcionara! Después de tu comentario, lo hice así: return $this->hasMany('App\Article')->select(['id', 'title', 'user_id']); Esa clave foránea fue la respuesta. Gracias @patricus

    – Tony

    4 mayo 2015 a las 22:54


  • Lo probé y ¿por qué siempre devuelve una matriz vacía? alguna solución nueva para laravel 5.6?

    – Muhammad Dyas Yaskur

    7 sep 2018 a las 12:42

  • @MuhammadDyasYaskur verifique el NB “Para las opciones 1 y 2 anteriores, la clave externa (user_id) debe seleccionarse para que Laravel sepa cómo vincular los modelos al construir las relaciones”.

    – analizar

    8 de diciembre de 2020 a las 12:52

Avatar de usuario de Jesvin
Jesvin

<?php
$data = \App\User::with('articles:id,title,user_id')->get();

user_id es importante en tiene muchos relaciones

  • Eres un salvavidas, // *user_id es importante en las relaciones hasmay (gran hombre). Gracias

    – dipenparmar12

    13 de febrero de 2020 a las 19:05

Avatar de usuario de Karim Haddad
Karim Haddad

Sé que esta pregunta es antigua, pero quiero resaltar el problema: cuando desee seleccionar ciertos campos en la relación de Laravel, debe pasar la clave principal en la selección para obtener los datos en lugar de nulos.

¿Ha sido útil esta solución?