Laravel not displaying correct topic from database

Published 5 months ago by Rainieren

My problem is the following. I'm making a forum and It doesn't show the topic that I clicked on but another topic from the database. It is supposed to show Topic 19 but it shows Topic 1. The URL is correct. but it shows the wrong topic. Also. As you can see in this GIF: http://imgur.com/a/AfmPZ if u look at the picture and the username, it gets clear what's wrong. How can I solve this? Thank you in advance.

Topic.blade.php (Shows the topic)

<div class="container first-container">
    <div class="row first-row">
        <div class="col s12">
            @if(Auth::check())
            <div class="card">
                <div class="card-content clearfix">
                    <span class="card-title">{{ $theme->theme_title }} - {{ $topic->topic_title }}&nbsp;<span class="status-badge status-open">Open</span></span>
                    <a href="" class="btn blue-grey darken-4">Reply</a>
                </div>
            </div>
            @endif

            <div class="card blue-grey lighten-5">
                <div class="card-content">
                    <div class="collection">
                        <div class="collection-item row">
                            <div class="col s3">
                                <div class="avatar collection-link">
                                    <div class="row">
                                        <div class="col s3"><img src="/uploads/avatars/{{ $topic->user->avatar }}" class="circle responsive-img" style="w"></div>
                                        <div class="col s9">
                                            <p class="user-name">{{ $topic->user->username }} @if($topic->user->isAdmin())<i class="material-icons verified">verified_user</i>@elseif($topic->user->isModerator())<i class="material-icons mod">supervisor_account</i>@endif </p>
                                        </div>
                                    </div>
                                    <p>{{ $topic->user->role->role_name }}</p>
                                    <p>Vanaf: {{ $topic->user->created_at }}</p>
                                    <p class="post-timestamp">Posted n: {{$topic->created_at}}</p>
                                </div>
                            </div>
                            <div class="col s9">
                                <div class="row last-row">
                                    <div class="col s12">
                                        <h6 class="title">{{ $topic->topic_title }}</h6>
                                        <p>{!! $topic->topic_text !!}</p>
                                    </div>
                                </div>
                                <div class="row last-row block-timestamp">
                                    <div class="col s6">
                                        <p class="post-timestamp">Last changed: {{ $topic->updated_at }}</p>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="card">
                <div class="card-content">
                    @foreach($topic->replies as $reply)
                    <div class="collection">
                            <div class="collection-item row">
                                <div class="col s3">
                                    <div href="" class="avatar collection-link">
                                        <div class="row">
                                            <div class="col s3"><img src="/uploads/avatars/{{ $reply->user->avatar }}" alt="" class="circle" style="width: 50px;"></div>
                                            <div class="col s9">
                                                <p class="user-name">{{ $reply->user->username }} @if($reply->user->isAdmin())<i class="material-icons verified">verified_user</i>@elseif($reply->user->isModerator())<i class="material-icons mod">supervisor_account</i>@endif</p>
                                            </div>
                                        </div>
                                        <p>{{ $reply->user->role->role_name }}</p>
                                        <p>Vanaf: {{ $reply->user->created_at }}</p>
                                        <p class="post-timestamp">Gepost op: {{ $reply->created_at }}</p>
                                    </div>
                                </div>
                                <div class="col s9">
                                    <div class="row last-row">
                                        <div class="col s12">
                                            <p>{!! $reply->reply_text !!}</p>
                                        </div>
                                    </div>
                                    <div class="row last-row block-timestamp">
                                        <div class="col s6">
                                            <p class="post-timestamp">Laatst aangepast op: {{ $reply->updated_at }}</p>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    @endforeach
                </div>
            </div>
                @if(Auth::check())
                    <div class="card">
                        <div class="card-content clearfix">
                            <a href="" class="btn blue-grey darken-4">Reply</a>
                        </div>
                    </div>
                @endif
        </div>
    </div>
</div>

Theme.blade.php (The view with the link to the topic)

<div class="col s12">
                <div class="card">
                    <div class="card-content"><span class="card-title">{{ $theme->theme_title }} - Topics</span>
                        <div class="collection">
                            @foreach($theme->topics as $topic)
                                <a href="{{ route('showtopic', ['theme_id' => $theme->id, 'topic_id' => $topic->id ]) }}" class="collection-item avatar collection-link"><img src="/uploads/avatars/{{ $topic->user->avatar }}" alt="" class="circle">
                                    <div class="row">
                                        <div class="col s6">
                                            <div class="row last-row">
                                                <div class="col s12"><span class="card-title">{{ $topic->topic_title }}</span>
                                                    <p>{!! str_limit($topic->topic_text, $limit = 125, $end = '...') !!}</p>
                                                </div>
                                            </div>
                                            <div class="row last-row">
                                                <div class="col s12 post-timestamp">Posted by: {{ $topic->user->username }} on: {{  $topic->created_at }}</div>
                                            </div>
                                        </div>
                                        <div class="col s2">
                                            <h6 class="title center-align">Replies</h6>
                                            <p class="center replies">{{ $topic->replies->count() }}</p>
                                        </div>
                                        <div class="col s2">
                                            <h6 class="title center-align">Status</h6>
                                            <div class="status-wrapper center-align"><span class="status-badge status-open">open</span></div>
                                        </div>
                                        <div class="col s2">
                                            <h6 class="title center-align">Last reply</h6>
                                            <p class="center-align">Naam</p>
                                            <p class="center-align">Tijd</p>
                                        </div>
                                    </div>
                                </a>
                            @endforeach
                        </div>
                    </div>
                </div>
            </div>

Web.php (Routes)

Route::get('/theme/{theme_id}/topics', '[email protected]')->name('showtheme');
Route::get('/theme/{theme_id}/topics/{topic_id}', '[email protected]')->name('showtopic');

TopicsController.php (Show method that is supposed to show the correct topic)

{
        $topic = Topic::find($id);
        $theme = Theme::with('topics')->find($id);

        return view('topics.topic')->with('topic', $topic)->with('theme', $theme);

    }
Best Answer (As Selected By Rainieren)
Snapey

Scenario #1

ok, lets just say that a topic can belong to many theme

and that at this point in the process you are wanting to display the topic and show what theme it is in. Since the topic can belong to many themes, you don't know which one to show.

In which case, the url can be like /theme/{theme_id}/topic/{topic_id}

In the theme view where you want to click and go to topic, create a link like

<a href="{{ route('topic',[$theme->id,$topic->id]) }}">{{ $topic->topic_title }}</a>

In the controller, grab the two models by their id's

public function show($theme_id, $topic_id);
{
    $theme = Theme::findOrFail($theme_id);

    $topic = Topic::findOrFail($topic_id);

    return view('topic')->withTheme($theme)->withTopic($topic);
}

Scenario #2

ok, lets just say that a topic can belong to only one theme

At this point you want to show the topic and which theme it belongs

In which case, the url can be like /topic/{topic_id}

In the theme view where you want to click and go to topic, create a link like

<a href="{{ route('topic',$topic->id) }}">{{ $topic->topic_title }}</a>

In the controller, grab the topic model by its id, and eager load the theme

public function show($topic_id);
{
    
    $topic = Topic::with('theme')->findOrFail($topic_id);

    return view('topic')->withTheme($topic->theme)->withTopic($topic);
}

On that final line, notice the $topic->theme - this is so that you have a $theme variable and don't have to use $topic everywhere you want theme information in the view

In both scenarios, you now have $theme and $topic available to display

Cronix
Cronix
5 months ago (175,200 XP)

because you are getting the topic by the passed in id, and then also getting the theme by the same id. That's not what you want.

I showed you how to get the one theme by it's id, WITH it's associated topics in your previous post.

You don't need to get topic at all ($topic = Topic::find($id);). Just use the $theme = Theme::with('topics')->find($id); which will get BOTH.

It will get the one theme by the passed in $id, and then it will also get all of the topics associated with that one theme.

Rainieren

I think i'm not thinking straight or something. But it still does the same It is supposed to show the topic of ffeeney but shows the topic of henry62. I have this in my show method now

public function show($id)
    {
        $topic = Topic::with('theme')->find($id);
        $theme = Theme::with('topics')->find($id);

        return view('topics.topic')->with('theme', $theme)->with('topic', $topic);

    }

And this is the view Topic.blade.php

@section('content')
<div class="container first-container">
    <div class="row first-row">
        <div class="col s12">
            @if(Auth::check())
            <div class="card">
                <div class="card-content clearfix">
                    <span class="card-title">{{ $theme->theme_title }} - {{ $topic->topic_title }}&nbsp;<span class="status-badge status-open">Open</span></span>
                    <a href="" class="btn blue-grey darken-4">Reply</a>
                </div>
            </div>
            @endif

            <div class="card blue-grey lighten-5">
                <div class="card-content">
                    <div class="collection">
                        <div class="collection-item row">
                            <div class="col s3">
                                <div class="avatar collection-link">
                                    <div class="row">
                                        <div class="col s3"><img src="/uploads/avatars/{{ $topic->user->avatar }}" class="circle responsive-img" style=""></div>
                                        <div class="col s9">
                                            <p class="user-name">{{ $topic->user->username }} @if($topic->user->isAdmin())<i class="material-icons verified">verified_user</i>@elseif($topic->user->isModerator())<i class="material-icons mod">supervisor_account</i>@endif </p>
                                        </div>
                                    </div>
                                    <p>{{ $topic->user->role->role_name }}</p>
                                    <p>Vanaf: {{ $topic->user->created_at }}</p>
                                    <p class="post-timestamp">Posted n: {{$topic->created_at}}</p>
                                </div>
                            </div>
                            <div class="col s9">
                                <div class="row last-row">
                                    <div class="col s12">
                                        <h6 class="title">{{ $topic->topic_title }}</h6>
                                        <p>{!! $topic->topic_text !!}</p>
                                    </div>
                                </div>
                                <div class="row last-row block-timestamp">
                                    <div class="col s6">
                                        <p class="post-timestamp">Last changed: {{ $topic->updated_at }}</p>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="card">
                <div class="card-content">
                    @foreach($topic->replies as $reply)
                    <div class="collection">
                            <div class="collection-item row">
                                <div class="col s3">
                                    <div href="" class="avatar collection-link">
                                        <div class="row">
                                            <div class="col s3"><img src="/uploads/avatars/{{ $reply->user->avatar }}" alt="" class="circle" style="width: 50px;"></div>
                                            <div class="col s9">
                                                <p class="user-name">{{ $reply->user->username }} @if($reply->user->isAdmin())<i class="material-icons verified">verified_user</i>@elseif($reply->user->isModerator())<i class="material-icons mod">supervisor_account</i>@endif</p>
                                            </div>
                                        </div>
                                        <p>{{ $reply->user->role->role_name }}</p>
                                        <p>Vanaf: {{ $reply->user->created_at }}</p>
                                        <p class="post-timestamp">Gepost op: {{ $reply->created_at }}</p>
                                    </div>
                                </div>
                                <div class="col s9">
                                    <div class="row last-row">
                                        <div class="col s12">
                                            <p>{!! $reply->reply_text !!}</p>
                                        </div>
                                    </div>
                                    <div class="row last-row block-timestamp">
                                        <div class="col s6">
                                            <p class="post-timestamp">Laatst aangepast op: {{ $reply->updated_at }}</p>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    @endforeach
                </div>
            </div>
                @if(Auth::check())
                    <div class="card">
                        <div class="card-content clearfix">
                            <a href="" class="btn blue-grey darken-4">Reply</a>
                        </div>
                    </div>
                @endif
        </div>
    </div>
</div>
webmind

Try this:

public function show(Request $request)
    {
        $r=$request->all();
        $theme_id = $r['theme_id'];
        $topic_id = $r['topic_id']
        $topic = Topic::with('theme')->find($topic_id);
        $theme = Theme::with('topics')->find($theme);

        return view('topics.topic')->with('theme', $theme)->with('topic', $topic);

    }
Snapey
Snapey
5 months ago (707,455 XP)

i cannot fathom what you are trying to do, but one thing is clear, you pass two ids to the route but then only accept the one $id in the show method?

just take a breath, and plan what you want to happen

are you clicking on a topic (don't need the theme id) or are you clicking on a theme (don't need the topic id)

Rainieren

Snapey, What I'm trying to do is, is that it needs to show the topic that the user clicked on but it doesn't do that. Instead, it shows a random topic. But it's the view that is supposed to show the topic also need te have the $theme variable so I can get the title of the theme were the topic is in. If u read this carefully it will make sense I hope. I can tell my explanations are not that great because no one every truly understands me. I hope this is a good explanation though

Snapey
Snapey
5 months ago (707,455 XP)

Scenario #1

ok, lets just say that a topic can belong to many theme

and that at this point in the process you are wanting to display the topic and show what theme it is in. Since the topic can belong to many themes, you don't know which one to show.

In which case, the url can be like /theme/{theme_id}/topic/{topic_id}

In the theme view where you want to click and go to topic, create a link like

<a href="{{ route('topic',[$theme->id,$topic->id]) }}">{{ $topic->topic_title }}</a>

In the controller, grab the two models by their id's

public function show($theme_id, $topic_id);
{
    $theme = Theme::findOrFail($theme_id);

    $topic = Topic::findOrFail($topic_id);

    return view('topic')->withTheme($theme)->withTopic($topic);
}

Scenario #2

ok, lets just say that a topic can belong to only one theme

At this point you want to show the topic and which theme it belongs

In which case, the url can be like /topic/{topic_id}

In the theme view where you want to click and go to topic, create a link like

<a href="{{ route('topic',$topic->id) }}">{{ $topic->topic_title }}</a>

In the controller, grab the topic model by its id, and eager load the theme

public function show($topic_id);
{
    
    $topic = Topic::with('theme')->findOrFail($topic_id);

    return view('topic')->withTheme($topic->theme)->withTopic($topic);
}

On that final line, notice the $topic->theme - this is so that you have a $theme variable and don't have to use $topic everywhere you want theme information in the view

In both scenarios, you now have $theme and $topic available to display

Rainieren

Snapey, In your reply the case for this problem is Scenario #2, A topic belongs to a theme. BUT a theme can have many topics. The link in the theme.blade.php looks like this <a href="{{ route('showtopic', ['theme_id' => $theme->id, 'topic_id' => $topic->id ]) }}" And my show method looks like this.

public function show($topic_id)
    {
        $topic = Topic::with('theme')->findOrFail($topic_id);

        return view('topics.topic')->with($topic->theme)->withTopic($topic);

    }

But this still gives me the error Illegal offset type'. I think the URL shows just fine. Because it shows http://forum.dev/theme/1/topics/19 Which is equal to forum.dev/theme/{theme_id}/topics/{topic_id}. Because if u look at this picture http://imgur.com/a/ljQPm u can see that the topic (With the cat picture) has ID 19. That's also visible in the database: http://imgur.com/a/oFD0E

I honestly don't know how to explain this better since I'm not English but I'm trying. I hope this makes some things clearer.

Snapey
Snapey
5 months ago (707,455 XP)

As in Scenario 2 then, you DONT need to pass theme in the URL.

Just remove it.,

href="{{ route('showtopic', ['topic_id' => $topic->id ]) }}"

and then it won't be confused with the themeID

ps, @ reply so that the person mentioned gets a flag

Rainieren

@Snapey I think I don't see this the right way as you do.If I change the link to this: <a href="{{ route('showtopic', ['topic_id' => $topic->id ]) }}". I get the error Missing required parameters for [Route: showtopic] [URI: theme/{theme_id}/topics/{topic_id}]. (View: C:\xampp\htdocs\laravel\forum\resources\views\themes\theme.blade.php) Be aware that the link is in a foreach loop. I dont know if this could affect it. But it looks like this and it works: @foreach($theme->topics as $topic) This is still in the Theme.blade.php.

My TopicsController.php looks like this. I took this from your Scenario #2.

public function show($topic_id)
    {
        $topic = Topic::with('theme')->findOrFail($topic_id); 

        return view('topics.topic')->with($topic->theme)->withTopic($topic);

    }

I know it is something I've done before on a previous project. But there it works just fine. but here it does not. Thanks for helping me by the way

Snapey
Snapey
5 months ago (707,455 XP)

Also remove theme from the route in Web.php it is not needed

Rainieren

@Snapey What do you mean remove theme in my web.php? which route?

Snapey
Snapey
5 months ago (707,455 XP)

the route that displays the single topic

Rainieren

@Snapey This is supposed to bring the user to the single topic. Route::get('/theme/{theme_id}/topics/{topic_id}', '[email protected]')->name('showtopic');

public function show($id)
    {
        $topic = Topic::with('theme')->find($id);
        $theme = Theme::with('topics')->find($id);

        return view('topics.topic')->with('theme', $theme)->with('topic', $topic);

    }

There is nothing with a theme in there except the Theme_id. but that is necessary for the URL to work right? The URL is supposed to be like.

If the user clicks on a theme with the theme_id 1. the URL is forum.dev/theme/1/topics. So far so good. The user gets an overview of every topic with the theme_id 1. If the user clicks on a topic in that overview with the (in this case) topic_id 19 the URL is supposed te be like forum.dev/theme/1/topics/19. This link works just fine no problems there. But the post doesn't show the one with topic_id 19 but instead, shows a topic with ID 1. That's the problem here.

In my case the THEME I clicked on has theme_id 1. Every topic with theme_id 1 gets displayed. So far so good. Now if I click on (In this case) the topic of "ffeeney" with the topic_id of 19. It is supposed to show the topic with the topic_id 19 right? And that's where the problem is. Instead of showing topic_id 19. It shows topic_id 1 and topic_id 1 has a theme_id of 9. Which does not make sense. I uploaded a 30-second video on youtube which visualises the problem. https://youtu.be/7UpabVE3GKU. I hope this make thing clear.

Snapey
Snapey
5 months ago (707,455 XP)

There is nothing with a theme in there except the Theme_id. but that is necessary for the URL to work right? The URL is supposed to be like.

No

We can go over it all again...

on a topic in that overview with the (in this case) topic_id 19 the URL is supposed te be like forum.dev/theme/1/topics/19. This link works just fine no problems there. But the post doesn't show the one with topic_id 19 but instead, shows a topic with ID 1. That's the problem here.

if you are fixed on this pattern then, I give up, lets do it your way (pointless)

route;

Route::get('/theme/{theme_id}/topics/{topic_id}', '[email protected]')->name('showtopic');`

Controller;

public function show($theme_id, $topic_id)
    {
        $topic = Topic::find($topic_id);
        $theme = Theme::find($theme_id);

        return view('topics.topic')->with('theme', $theme)->with('topic', $topic);

    }

Theme view

<a href="{{ route('showtopic', ['theme_id'=>$theme->id,'topic_id' => $topic->id ]) }}"

The point is, if you have two parameters in the route then you should have two parameters passed into the controller

Earlier I was trying to make you see that you don't need the theme_id but I give up.

Rainieren

@Snapey I tried your way but it gave me an error as I said,

If I did it correctly. My theme and Controller looks like this if I try your way. theme.blade.php( the link)

<a href="{{ route('showtopic', $topic->id ) }}">

I changed the topic to showtopic because route 'topic' does not exist in web.php. And this is what my TopicsController looks like

public function show($topic_id)
    {

        $topic = Topic::with('theme')->findOrFail($topic_id);

        return view('topics.topic')->withTheme($topic->theme)->withTopic($topic);

    }

This is everything that you said in Scenario #2. Correct it if I'm wrong. But this gives me the error Missing required parameters for [Route: showtopic] [URI: theme/{theme_id}/topics/{topic_id}].

If I read the code this should just work and give me the correct topic (The one with theme_id 1 and topic_id 19). But it gives me the error above.

Please sign in or create an account to participate in this conversation.