1
votes

Laravel Collection obtient l'une des valeurs par clé

Je suis nouveau sur Laravel et j'essaie d'obtenir l'une des valeurs d'une collection par un identifiant récupéré d'une autre collection.

Ma fonction renvoie 2 collections:

public function up()
{
    Schema::create('blog_posts', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('title');
        $table->longText('content');
        $table->mediumText('slug');
        $table->bigInteger('author_id')->unsigned();
        $table->bigInteger('category_id')->unsigned();
        $table->timestamps();
        $table->foreign('author_id')->references('id')->on('blog_authors');
        $table->foreign('category_id')->references('id')->on('blog_categories');
    });
}

Dans une boucle foreach, j'obtiens des valeurs de collections:

    @foreach($posts as $post)
     @if($loop->iteration > 2)
        <div class="col-sm-6 col-md-3 d-flex justify-content-center other-post">
          <a href="#">
             <img src="#" alt="">
             <p class="post-category">{{ $categories->get($post->category_id) }}</p>
             <h5 class="post-title">{{ $post->title }}</h5>                        
          </a>
         </div>
      @endif
     @endforeach

J'obtiens partiellement le résultat comme vous pouvez le voir dans l'image ci-dessous, mais je ne veux obtenir que le nom.

 Exemple de résultat

Voici le code que j'essaye de comprendre {{$ categories-> get ($ post-> category_id)}}

S'il y a une meilleure ou une bonne façon de le faire, faites-le moi savoir.

Migration des articles de blog:

public function index()
{
    $category = BlogCategory::all(['id', 'name']);        
    $post = BlogPost::orderBy('id', 'desc')->take(14)->get();
    return view('blog.index', ['posts' => $post],  ['categories' => $category]);
}


0 commentaires

4 Réponses :


0
votes

cette ligne $ categories-> get ($ post-> category_id) renvoie pour vous un tableau de category , donc la solution pour vous ici est comme ci-dessous:

{{ $categories->get($post->category_id)['name'] }}


4 commentaires

Cela donne une erreur: Essayer d'obtenir la propriété 'nom' d'un non-objet


Tentative d'obtention du nom de la propriété d'un non-objet


@AlanGodoidaSilveira en fait, car la valeur renvoyée par la méthode get est un simple tableau, vérifiez maintenant


qu'entendez-vous par ordre, s'il vous plaît? combien de noms par ligne avez-vous?



1
votes

Cela pourrait être optimisé, tout d'abord, vous devez établir une relation un à plusieurs des catégories aux articles

d'abord : assurez-vous que vous avez dans les messages les migrations category_id colonne

Deuxième : Ouvrez le modèle de catégorie et écrivez cette méthode, cela vous permettra de récupérer les articles qui appartiennent à la catégorie

public function index()
{        
  $post = BlogPost::orderBy('id', 'desc')->take(14)
          ->with('category')->get();
  return view('blog.index', ['posts' => $post]);
}

Troisième : ouvrez le modèle de boutique et écrivez cette méthode, cela vous permettra de récupérer la catégorie qui appartient à l'article

@foreach($posts as $post)
    <div class="col-sm-6 col-md-3 d-flex justify-content-center other-post">
      <a href="#">
         <img src="#" alt="">
         <p class="post-category">{{ $post->category->title }}</p>
         <h5 class="post-title">{{ $post->title }}</h5>                        
      </a>
     </div>
 @endforeach

Enfin strong>: vous modifierez votre vue comme celle-ci

public function catgeory(){
   return $this->belongsTo(\App\Category::class);
}

et bien sûr, vous n'appelerez plus les catégories dans votre contrôleur

public function posts(){
   return $this->hasMany(\App\Post::class);
}


7 commentaires

Vous avez oublié de charger des catégories avec BlogPost, votre contrôleur / code de vue enverra 15 requêtes au lieu de seulement deux.


Gentil je l'oublie je vais le réparer maintenant merci de m'avoir remarqué


Appel à une relation non définie [catégories] sur le modèle [App \ BlogPost]


désolé, j'écris des catégories au lieu de la catégorie dans le contrôleur, ce sera comme ceci $ post = BlogPost :: orderBy ('id', 'desc') -> take (14) -> with ('category') -> get ();


Oui, cela a fonctionné. Mais j'ai essayé une autre bonne réponse avant la vôtre.


@AlanGodoidaSilveira merci :) mais je mentionnerais quelque chose la réponse avant de faire (n + 2) requête SQL parce que chaque fois que vous dites $ post-> category-> title cela fait une nouvelle requête mais dans mon cas , il le composera dans la première requête du contrôleur en utilisant la méthode with () cette technique appelée chargement hâtif


Sûr. La réponse acceptée utilise également le chargement hâtif.



0
votes

Il vaut peut-être mieux utiliser une relation pour conduire cette situation. Vous pouvez charger dans le contrôleur les données de cette manière.

Dans le post modèle:

@foreach($posts as $post)
     @if($loop->iteration > 2)
        <div class="col-sm-6 col-md-3 d-flex justify-content-center other-post">
          <a href="#">
             <img src="#" alt="">
             <p class="post-category">{{ $post->categories->name }}</p>
             <h5 class="post-title">{{ $post->title }}</h5>                        
          </a>
         </div>
      @endif
     @endforeach

Peut-être est hasOne -> la relation si vous n'avez pas de table pivot ...

Dans le contrôleur:

    public function index()
{     
    $data['posts'] = BlogPost::orderBy('id', 'desc')->take(14)->with('categories')->get();
    return view('blog.index', $data);
}

Dans la vue:

function categories(){
return $this->belongsToMany('App\BlogCategory')->select(array('id', 'name');
}


4 commentaires

Avec appartientToMany: Table de base ou vue non trouvée: 1146 La table 'eaglehorn.blog_category_blog_post' n'existe pas (SQL: sélectionnez id , nom , blog_category_blog_post`


Avec hasOne: Colonne introuvable: 1054 Colonne inconnue 'blog_categories.blog_post_id'


Vous devez ajouter une colonne reliant les deux tables. Peut-être que si le champ associé est category_id: return $ this-> hasOne ('App \ BlogCategory', 'category_id') -> select (arra‌ y ('id', 'name');


Informations de charge de relation liées entre les tables. Vérifiez les informations sur: si la relation est un à un: laravel.com / docs / master / eloquent-relations # one-to-one si vous avez des catégories pour chaque message: une à plusieurs laravel.com/docs/master/eloquent-relationships#one-to-many



1
votes

Vous devez mettre en place les relations entre les modèles BlogPost et BlogCategory , vu que vous avez déjà un champ category_id dans BlogPost modèle, c'est-à-dire:

dans BlogPost Modèle:

@foreach($posts as $post)
 @if($loop->iteration > 2)
    <div class="col-sm-6 col-md-3 d-flex justify-content-center other-post">
      <a href="#">
         <img src="#" alt="">
         <p class="post-category">{{ $post->category->name }}</p>
         <h5 class="post-title">{{ $post->title }}</h5>                        
      </a>
     </div>
  @endif
 @endforeach

dans BlogCategory Modèle: p>

public function index()
{        
    $posts = BlogPost::with('category')->orderBy('id', 'desc')->take(14)->get();
    return view('blog.index', compact('posts'));
}

Ensuite, vous pouvez charger avec impatience catégories avec les $ posts dans votre contrôleur avec seulement deux requêtes:

public function posts(){
   return $this->hasMany(\App\BlogPost::class);
}

Puis dans votre vue vous pouvez accéder directement à chaque objet $ post-> category car impatient chargé dans le contrôleur:

public function category(){
   return $this->belongsTo(\App\BlogCategory::class);
}


7 commentaires

"Variable non définie: catégories"


Je n'ai pas de variable $ categories dans mon code que vous auriez dû publier dans la mauvaise réponse, veuillez essayer mon code.


Sûr. Il était nécessaire de redémarrer le serveur. Cela a fonctionné au besoin.


utiliser le chargement hâtif au lieu du chargement paresseux, cela fera (n + 2) opération SQL


Je ne pense pas @Joseph, le code contrôleur / vue que j'ai posté n'exécute que deux requêtes sur le modèle BlogPost et BlogCategory, essayez-le par vous-même.


faites dd () dans votre collection de messages et vérifiez s'il contient un objet de catégorie, vous ne le trouverez pas.


le contrôleur est impatient de charger: BlogPost :: avec ('category') qui sont deux requêtes, veuillez lire ici: laravel.com/docs/5.8/eloquent-relationships#eager-loading