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.
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]); }
4 Réponses :
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'] }}
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?
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); }
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.
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'); }
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
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); }
"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