3

i want to find post by slug also in url .. but the comments must be found by post_id

Controller

public function post($slug,$id)
{
    $post = Post::where('slug',$slug)->first();
    $comments = Comment::where('post_id',$id)->get();
    return view('content.post',compact('post','comments'));
}

Route

Route::get('post/{slug}', 'PagesController@post')->name('post.show');
Hamad Essa
  • 81
  • 1
  • 8
  • is this `$id` not equal to `$post` id? – V-K Feb 17 '20 at 13:26
  • Does this answer your question? [How to use variables in routes in laravel?](https://stackoverflow.com/questions/41466153/how-to-use-variables-in-routes-in-laravel) – loic.lopez Feb 17 '20 at 13:28

4 Answers4

2
Route::get('post/{slug}', 'PagesController@post')->name('post.show');
public function post($slug)
{
    $post = Post::where('slug',$slug)->first();
    $comments = Comment::where('post_id',$post->id)->get();
    return view('content.post',compact('post','comments'));
}
Wahyu Kristianto
  • 8,719
  • 6
  • 43
  • 68
  • 2
    This answer doesn't handle errors. If a Post entity isn't found by the provided slug, you will get a notice and a method call error, that isn't handled. – Repox Feb 17 '20 at 13:48
  • Just change `$post = Post::where('slug',$slug)->first() or abort(404);` to handle error (not found) – Wahyu Kristianto Feb 17 '20 at 13:54
  • 1
    @WahyuKristianto Or use proper model binding instead, which would handle this out of the box without additional code to the controller. – Repox Feb 18 '20 at 07:24
0

Here you go:

Get post_id from the $post itself.

public function post($slug){
    $post = Post::where('slug',$slug)->first();
    $comments = Comment::where('post_id',$post->id)->get();
    ...
}
Qumber
  • 13,130
  • 4
  • 18
  • 33
0

in web.php:

Route::get('post/{slug}', 'PagesController@post')->name('post.show');

in controller:

public function post($slug)
{
    $post = Post::where('slug',$slug)->first();
    $comments = Comment::where('post_id',$post->id)->get(); //use founded_post_id to find it's comments
    return view('content.post',compact('post','comments'));
}
Reza sh
  • 787
  • 10
  • 20
  • i edited my answer, you can reach your `$post` by `slug` and then reach to it's comments by using `$post->id` like my answer, in this way in url your id won't show – Reza sh Feb 18 '20 at 05:48
0

You can use Route Model Binding to ensure that routes will find your model based on the provided key.

Your Post model will require that you add the following method:

public function getRouteKeyName()
{
    return 'slug';
}

Then, in your routes, you can just refer the model directly, and binding will happen automatically:

public function post(App\Post $post)
{
    $comments = Comment::where('post_id',$post->id)->get();
    return view('content.post',compact('post','comments'));
}

This enables you to to use the following route:

Route::get('post/{post}', 'PagesController@post')->name('post.show');

Now, additionally, to ease up your reference of the comments, add them as relations to your Post model:

public function comments() 
{
    return $this->hasMany(Comment::class);
}

and your Comment model:

public function post()
{
    return $this->belongsTo(Post::class);
}

This will allow you to shorten your controller method even more:

public function post(App\Post $post)
{
    return view('content.post',compact('post'));
}

and in your Blade view do the following instead:

@foreach($post->comments as $comment)
From: {{ $comment->name }} blah blha
@endforeach
Repox
  • 15,015
  • 8
  • 54
  • 79