lara30453's avatar

Get all articles and render them out in their topic list

I have a site which has articles, categories and topics. The tables are structured as follows: category table has an id and category_name. The Article table has a Title, body, author_id, id, category_id, topic_id. The topic table has an id, category_id and topic_name. The relationships are: the article table has many categories and belongs to an author, the category table has many topics and belongs to a article and the topic table belongs to the category table.

On my home page, I want gather all this information and render it out in this format: category > topic > article - where category would be politics > election > bernie-sanders. How would I do this in my controller ?

article model

<?php

namespace Politicentral;

use Politicentral\User;
use Politicentral\Categories;
use Illuminate\Database\Eloquent\Model;

class Articles extends Model {
    
    protected $fillable = [
        'title', 
        'body', 
        'article_image',
    ];

    public function author() {

        return $this->belongsTo('Politicentral\User');
    }

    public function categories() {

        return $this->hasMany('Politicentral\Categories');
    }
}

category model

<?php

namespace Politicentral;

use Politicentral\Articles;
use Politicentral\Topics;
use Illuminate\Database\Eloquent\Model;

class Categories extends Model {

    protected $fillable = [
        'id', 
        'category_name', 
    ];

    public function articles() {

        return $this->belongsTo('Politicentral\Articles');
    }
}

topic model

<?php

namespace Politicentral;

use Politicentral\Categories;
use Illuminate\Database\Eloquent\Model;

class Topics extends Model {

    protected $fillable = [
        'id', 
        'topic_name', 
    ];

    public function categories() {

        return $this->belongsTo('Politicentral\Categories');
    }
}

Home controller

<?php

namespace Politicentral\Http\Controllers;

use Politicentral\User;
use Politicentral\Topics;
use Politicentral\Articles;
use Politicentral\Categories;

class HomeController extends Controller {

    public function show() {

        return view('home');
    }

}

blade partial

                <section class="postSection">

                    <a href="" class="topic">2016 Election</a>

                    <div class="article">
                        <div class="postImage" style="background-image: url(https://espnfivethirtyeight.files.wordpress.com/2016/04/ap_197674438310.jpg?w=575);"></div>
                        <div class="postInfo">
                            <div class="postDate">Posted on 9th April 2016</div>
                            <a href="" class="postHeading">Thinking They’re ‘Unqualified’ Is A Big Reason Why More Women Don’t Run For Office</a>
                            <a href="" class="postWriter">By Christie Loftus</a>
                        </div>
                    </div>

                </section>
0 likes
2 replies
jekinney's avatar

Add

namespace Politicentral;

use Politicentral\Categories;
use Illuminate\Database\Eloquent\Model;

class Topics extends Model {

    protected $fillable = [
        'id', 
        'topic_name', 
    ];

    public function categories() {

        return $this->belongsTo('Politicentral\Categories');
    }

  public function articles() {
    return $this->hasMany(Politicentral\Topics::class);
}
$categories = Category->with('topics', 'topics.articles')->get();

foreach($categories as $category)
{
    $category->name;
    foreach($category->topics as $topic)
    {
        $topic->name;
        foreach($topic->articles as $article)
        {
            $article->title;
        }
    }
}
lara30453's avatar

How would you strcuture the foreach in blade and how would you pass the data to the view? I am currently getting this error: "Call to undefined method Illuminate\Database\Query\Builder::topics()"

Controller

<?php

namespace Politicentral\Http\Controllers;

use Politicentral\User;
use Politicentral\Topics;
use Politicentral\Articles;
use Politicentral\Categories;

class HomeController extends Controller {

    public function show() {

        $latestArticles = Articles::with('author')
            ->take(4)
            ->orderBy('created_at', 'desc')
            ->get();

        $categories = Categories::with('topics', 'topics.articles')
            ->get();

        return view('home')
            ->with('latestArticles', $latestArticles)
            ->with('categories', $categories);
    }

}

topic model

<?php

namespace Politicentral;

use Politicentral\Topics;
use Politicentral\Categories;
use Illuminate\Database\Eloquent\Model;

class Topics extends Model {

    protected $fillable = [
        'id', 
        'topic_name', 
    ];

    public function categories() {

        return $this->belongsTo('Politicentral\Categories');
    }

    public function articles() {

        return $this->hasMany('Politicentral\Topics');
    }
}

blade page

@foreach($categories as $catergory)

                    <section class="postSection">

                        @foreach($category->topics as $topic)
                        
                            <a href="#" class="sectionHeading">{{  $topic->topic_name }}</a>

                        @endforeach

                        @foreach($topic->articles as $article)

                            <div class="post">
                                <div class="postImage" style="background-image: url({{ $article->article_image  }});"></div>
                                <div class="postInfo">
                                    <div class="postDate">{{ $article->created_at }}</div>
                                    <a href="" class="postHeading">{{ $article->title }}</a>
                                    <a href="www.twiiter.com/{{ $article->author()->first()->twitter }}" class="postWriter">By {{ $article->author()->first()->fullName() }}</a>
                                </div>
                            </div>

                        @endforeach

                    </section>

                @endforeach

Please or to participate in this conversation.