Bonjour,
je viens demander de l'aide SVP, car je n'arrive pas à faire quelques chose.

En suivant le tuto de Grafickart et en lisant la DOC : http://laravel.com/docs/5.1/eloquent-relationships#many-to-many
J'ai fait un système "belongsToMany".
Mon but est de pouvoir relier plusieurs articles à plusieurs catégories, et aussi de pouvoir relier plusieurs catégories à plusieurs articles.
J'ai donc 3 tables:
_article : où il y a mes articles.
_categoryarticles : où il y a mes categories.
_article_categoryarticle : ma table intermédiaire

Dans Mon édition (INSERT et UPDATE) d'articles, tout est OK.
Ce que je n'arrive pas à faire, c'est dans ma vues liste_articles de récupérer ma liste d'articles selon la catégorie séléctionnée.
Voici mon code de mon ArticleController :

<?php 
/**
* Retourne l'article WHERE statut
*/
private function returnArticle($status, $orderby, $order)
{
    if (isset($_GET['categorie'])) {
        $categorie = Categoryarticle::findOrFail($_GET['categorie']);   // récup la catégorie WHERE GET
        $articles_ids = $categorie->articles;              // récup articles associés à la catégorie
        //dd($articles_ids);

        $art = '';
        foreach ($articles_ids as $article_id) {
            $art .= Article::where('status', '=', $status)
                                        ->where('id', '=', $article_id)
                                        ->orderBy($orderby, $order)
                                        ->paginate(10);

            //echo $article_id->h1;     // m'affiche bien les titres
        }
        $this->articles = $art;
        //dd($this->articles);    // me renvoi : ""

// Ci dessous, sans le filtre par catégorie ça marche. le probleme est ci-dessus
    } else {
        $this->articles = Article::where('status', '=', $status)
                                    ->orderBy($orderby, $order)
                                    ->paginate(10);
    }

}

Ensuite j'envoi this->article dans la vue avec ceci:

return view('admin/articles/liste_articles, ['articles' => $this->articles]);

Et dans ma vue je fait un foreach.

Et voici mon code de mon model Categoryarticle :

<?php
/**
* Des catégories peuvent avoir plusieurs articles
* Faire la meme assos dans le model Article
*/
public function articles()
{
    return $this->belongsToMany('App\Article');
}

Voici mon code de mon model Article :

/**
* Des articles peuvent avoir plusieurs catégories
* Faire la meme assos dans le model Categoryarticle
*/
public function categoriesArticle()
{
    return $this->belongsToMany('App\Categoryarticle');     
}

Merci beaucoup

4 réponses


Azorgh
Réponse acceptée

Il faut que tu ajoute :

use Illuminate\Http\Request;

Pour la première erreur. (Lien doc).

Ensuite pour la pagination sur relation, tu as a première vue deux solutions (trouvés sur le net, et je te met les exemples pour que tu comprenne et que je fasse pas d'erreur).

  • La première :

    Product::find(1)->get()->options()->paginate(); 
  • La seconde :

    
    //Dans le model CategoryArticle
    public function getArticlesPaginatedAttribute()
    {
    return $this->articles()->paginate(10);
    }

//Dans ton controller
private function returnArticle($status, $orderby, $order, Request $request)
{
if ($request->get('categorie')) {
$this->articles = CategoryArticle::find($request->get('categorie'))->articles_paginated;
}
//etc ....
}



Je n'ai pas du tout testé, mais tente de partir là dessus.

Voici le post trouvé : 
http://www.helptouser.com/code/25497604-laravel-eloquent-pagination-on-relationships.html

C'est un peu le foulli ton truc là !

Voici ce que j'aurais fait (non testé) :

public function returnArticle($status, $orderby, $order, Request $request){
        $articles = null;

        if ($request->get('categorie')) {
            $articles = CategoryArticle::whereId($request->get('categorie'))->articles()->paginate(10);
        } else {
            $articles = Article::where('status', '=', $status)->orderBy($orderby, $order)->paginate(10);
        }

        return view('admin/articles/liste_articles', ['articles' => $articles]);
    }

Dans un premier temps, préfère utiliser les méthodes de laravel dispo, comme par exemple au lieu de $_GET[], préfère utiliser l'objet Request. (Voir la doc).
Ensuite, une relations eloquent ne te renvoit pas d'id, il te renvoi l'objet complet (dans ton foreach), donc la tu fait le double de requete pour rtien.

En plus dans ton foreach tu fait :

$maVar .= Model:: ......

Le '.' permet de concat des strings, pas des objets ! (A moins que ca fonctionne mais la ça m'étonne).
Donc préfère soit utiliser un tableau $articles[] = Model:: ....

Pour finir, un paginate se fait sur une requete avec plusieurs résultats ! La tu fait un paginate sur un seul résultat (puisque tu passe l'id).

stephweb
Auteur

Ok merci beaucoup.
j'ai essayé d'ajouter le Request dans ma function:

private function returnArticle($status, $orderby, $order, Request $request)

mais ça me renvoi cette erreur:
"Argument 4 passed to App\Http\Controllers\Base\ArticleController::returnArticle() must be an instance of Illuminate\Http\Request, none given, called in C:\wamp\www--Laravel\app\Http\Controllers\Base\ArticleController.php on line 145 and defined"

Et mem avec ceci ça ne fonctionne pas:

private function returnArticle($status, $orderby, $order)
{
    if (isset($_GET['categorie'])) {
        $this->articles = CategoryArticle::whereId($_GET['categorie'])->articles()->paginate(10);
    } else {
        $this->articles = Article::where('status', '=', $status)
                                    ->orderBy($orderby, $order)
                                    ->paginate(10);
    }
}

ça me renvoi cette erreur:
"Call to undefined method Illuminate\Database\Query\Builder::articles()".
Pourtant cette method existe bien dans mon model Categoryarticle.
comment faire?
Merci

stephweb
Auteur

Merci beaucoup. ta 2è solution fonctionne. sujet résolu