404 not found in laravel - laravel

hi m trying to show a data on show.blade.php but it says 404|not found m using resource route for it. Remember m shwing the students on teacher index and from there i wants to redirect it to student/show.blade.php
StudentController:
public function show(Student $student)
{
$data = Student::findOrFail($student->id);
return view('student.show', compact('data'));
}
teacher blade file:
<td>
#foreach($row->student as $st)
<a href="{{ route('student.show', $row->id) }}">
{{ $st->student_name }}</a>
#endforeach
</td>

you are passing id into your controller not a model so the correction is here
public function show($student)
{
$data = Student::findOrFail($student);
return view('student.show', compact('data'));
}
and also correct this part on your blade
<a href="{{ route('student.show', $st->id) }}">
you get error not found because $student->id is returning null because you sending incorrect looping part therefore you got error 404

I don't know your route to students, but If you have a route like this:
Route::get('students/{id}', 'StudentController#show')->name('student.show');
What is the name of the array that you are passing with student collection from
TeacherContoller? $data?
If so, your blade file "teacher.blade.php" would be like this:
<td>
#foreach($data as $row)
<a href="{{ route('student.show', ['id' => $row->id]) }}">
{{ $row->student_name }}</a>
#endforeach
</td>
Then, you would change your method to be like this:
/**
* #var int $id
*/
public function show(int $id)
{
$data = Student::findOrFail($id);
return view('student.show', compact('data'));
}

Related

I want to displaying comments for each post

hello I just moved from php native and want to try relationships in laravel, so I want to display a post and each comment and the name of user who comments so that when looped the post has a comment that has a relationship with it.
So this is my HomeController.php :
public function index() {
$posts = Post::all();
$comment = Comment::all();
return view('home', [
'posts' => $posts,
'comments' => $comment
]);
}
My Post.php :
public function comments() {
return $this->hasMany(Comment::class);
}
public function user() {
return $this->belongsTo(User::class);
}
My Comments.php :
public function post() {
return $this->belongsTo(Post::class);
}
public function user() {
return $this->belongsTo(User::class);
}
My User.php :
public function post() {
return $this->hasMany(Post::class);
}
My home.blade.php :
#foreach ($posts as $post)
<div class="box-post">
<p>{{ $post->user->name }}</p>
<p>{{ $post->post_content}}</p>
<button>Comment</button>
</div>
#foreach ($comments as $comment)
<div class="box-post">{{ $comment->comment_content }} </div>
#endforeach
#endforeach
the code above runs with the post displayed along with the author but all the comments also appear in all posts, I have searched for references and tried to change the comments value in Controller but the results are still the same so I made the comments appear in each post *$comment = Comment::all();.
what I want is to display posts and comments that relate to each post, like a twitter feature that can reply to people's tweets.
Thx you..
Your relations builded well, so just can simply use $post->comments can get all comments related on each post.
#foreach ($posts as $post)
<div class="box-post">
<p>{{ $post->user->name }}</p>
<p>{{ $post->post_content}}</p>
<button>Comment</button>
</div>
#foreach ($post->comments as $comment) // make changes here
<div class="box-post">{{ $comment->comment_content }} </div>
#endforeach
#endforeach
public function index() {
$posts = Post::with('comments')->get();
return view('home', [
'posts' => $posts,
]);
}
then in blade
#foreach ($posts as $post)
<div class="box-post">
<p>{{ $post->user->name }}</p>
<p>{{ $post->post_content}}</p>
<button>Comment</button>
</div>
#foreach ($post->comments as $comment)
<div class="box-post">{{ $comment->comment_content }} </div>
#endforeach
#endforeach
You have done fine job building models and their relationship.
I recommend you change how you call post query.
public function index(Request $request) {
// add eager loading comments for each post and user
$posts = Post::with('comments', 'user')->get();
// eager loading user is needed, cause in blade you call $post->user->name
// calling comments will no longer needed
// return only $posts
return view('home', compact('posts'));
}
And inside your blade, you can call comments from each post, like this.
#foreach ($posts as $post)
<div class="box-post">
<p>{{ $post->user->name }}</p>
<p>{{ $post->post_content}}</p>
<button>Comment</button>
</div>
#foreach ($post->comments as $comment)
<div class="box-post">{{ $comment->comment_content }} </div>
#endforeach
#endforeach
That's it and if you use barryvdh/laravel-debugbar , you will see there are only 3 queries run, each one from table posts, comments and users.
And for comments query and users query, not all rows will be fetched,
only related to fetched posts from the 1st query.
Have fun using Laravel Framework!
Your PHP native knowledge/expertise will be very useful and speed up your learning/mastering process.

is it okay to access model from view in MVC concept?

As along as I know, if the view want to access model, it needs to pass the controller in MVC concept.
And I wrote like the code below
#php
$topik_speaker = App\TopikSpeaker::with('get_topik')->where('id_pembicara',$e->id)->get();
#endphp
#foreach ($topik_speaker as $k)
<span class="badge badge-pill badge-sm badge-primary" style="background-color: #51b3f9">{{ $k->get_topik['topik'] }}</span>
#endforeach
Is it breaking the rule of MVC concept or not ?
You should return data from model or db in your controller like:
public function show()
{
$data = User::all();
return view('yourview')->with('data', $data);
}
In view you get this by accessing like:
#foreach($data as $user)
{{ $user->name }}
#endforeach

Use "where" and "limit" to child in #foreach

I want to display all user's profile into views and they posts. It's pretty simple:
#foreach($profiles as $profile)
{{ $profile->name }}
#foreach($profile->posts as $post)
{{$post->title}}
#endforeach
#endforeach
But I want to display only the latests posts (->orderBy('created_at', 'desc')->limit(4) ) and only accepted posts (->where('accept', 1)). How can I do that?
You already have what you need. You just need to put it all together.
#foreach($profile->posts()->where('accept', 1)->orderBy('created_at', 'desc')->limit(4)->get() as $post)
I would consider creating a query scope on your profile model. That way you can do something like $profile->latestPosts.
Or you can use the relationship to return exactly what you need.
public function latestPosts() {
return $this->posts()->where('accept', 1)->orderBy('created_at', 'desc')->limit(4)->get();
}
Then you could use it as:
#foreach($profile->latestPosts() as $post)
{{$post->title}}
#endforeach
A better solution would be to lazy load the posts you need when loading the profiles in the controller.
$profile = Profile::with(['posts' => function ($post) {
$post->where('accept', 1)->orderBy('created_at', 'desc')->limit(4);
}])->limit(10)->get();
then in the blade you can do the same as before
#foreach($profiles as $profile)
{{ $profile->name }}
#foreach($profile->posts as $post)
{{$post->title}}
#endforeach
#endforeach
if you want to use a scope for latestAccepted, you can on the Post model
class Post extends Model
{
public function scopeLatestAccepted($query)
{
return $query->where('accept', 1)->orderBy('created_at', 'desc')->limit(4)
}
}
Then lazy load it
$profile = Profile::with(['posts' => function ($post) {
$post->latestAccepted();
}])->limit(10)->get();
what you have to do is pretty simple.
create table users
create table post
create a relationships between the 2 tables
write you code in controller to join the table and query all the users post based on his/her username or password
see sample screenshot for table relationships
//Controller
Public function ViewPost(){
$data['data']=DB::table('useratable')
->where('useratable.username','=', $uname)
->where('useratable.password','<=',$pwd)
->leftjoin('posttable', 'useratable.idusertable', '=', 'posttable.userid')
->orderby('posttable.idposttable','desc')
->get();
}
//Route
Route::get('/view-post','YourController#ViewPost')
//view
#foreach($data as $r)
{{ $r->fullname}} <br>
{{ $r->email}} <br>
{{ $r->topic }} <br>
{{ $r->content }} <br>
{{ $r->datetime}} <br>
...
#endforeach
You need some codes like it on controller:
$profiles = Profile::with(['posts' => function ($query) {
$query->where('accept', 1)
->orderBy('created_at', 'desc');
}])->get();
And add this one to blade file:
#foreach($profiles as $profile)
{{ $profile->name }}
#foreach($profile->posts as $post)
{{$post->title}}
#if ($loop->iteration == 4)
#break
#endif
#endforeach
#endforeach

how to display dynamic value without using foreach loop in laravel

How to print these type of data in laravel.I am trying to create dynamic menu and these type of problem occurs.Code is like this. my code is like this.
In view composer.
public function compose(View $view)
{
$menus = $this->menu->getDynamicMenus();
$user_role = $this->role->lists('name', 'id');
//dd($user_role);
$view->with('user_role', $user_role)->with('menus', $menus);
}
menurepository code.
public function getDynamicMenus()
{
$user = $this->auth->user();
$roles = $user->roles;
// dd($roles);
$menus = [];
foreach ($roles as $role) {
//dd($role);
foreach ($role->menus as $menu) {
if ($menu["parent_id"] > 0) {
$menus[$menu["parent_id"]][$menu["id"]] = $menu->toArray();
} else {
$menus[$menu["id"]] = $menu->toArray();
}
}
}
// dd($menus);
return $menus;
}
and i print in frontend like.
#foreach($menus as $menu)
{{-- {!! Form::open() !!}
{!! Form::select('menus',$menus) !!}
{!! Form::close() !!}--}}
{{--{!! $menuitem->menu_name !!}--}}
{!! $menu->menu_url !!}
#endforeach
and it shows problem:
Trying to get property of non-object (View: E:\xampp\htdocs\basicwc\resources\views\layouts\partials\sidebar.blade.php) (View: E:\xampp\htdocs\basicwc\resources\views\layouts\partials\sidebar.blade.php) (View: E:\xampp\htdocs\basicwc\resources\views\layouts\partials\sidebar.blade.php)
as menu are getting in array like in image.
any help??
i tried to do like:
{!! menu($menus) !!}
but it says undefined problem.
I added another menu and it's structure is like this:
Access it like an array:
#foreach($menus as $menu)
...
{{ $menu['menu_name'] }}
{{ $menu['menu_url'] }}
#endforeach

Is there a more efficient way for grabbing the count of a model within the view? Laravel

I have Images. Each image has comments, and each comment has likes. In my view I'm wanting to display the number of likes a comment has by doing something like this:
#foreach ($images as image)
<img href="$image->url">
<div class="comment-box">
#foreach ($image->comments as $comment)
<div class="comment">
<span class="comment-owner">{{ $comment->owner()->name }}</span> {{ $comment->body }}
<div class="likes">
{{ $comment->likes()->count() }} // ** HERE IS MY N+1 PROBLEM **
</div>
</div>
#endforeach
</div>
#endforeach
However now I'm fetching a query each time there is a comment. There could be hundreds of comments on a page, so id be getting hundreds of queries just to find the count() for likes.
I believe there is a way you can grab the count in a controller by doing something like
DB::raw('count(*) as like_count')
but I do not know how to implement this in my situation. Can I put this kind of thing in my model so that I can always call something like {{ $comment->likes()->like_count }}? How can I make $comment->likes->count() work without having the N+1 problem?
Here is some more code:
Media Model
class Media extends Eloquent {
public function comments()
{
return $this->hasMany('Comment');
}
}
Comment Model
class Comment extends Eloquent {
public function media()
{
return $this->belongsTo('Media');
}
public function likes()
{
return $this->hasMany('Like');
}
}
Like Model
class Like extends Eloquent {
public function comment()
{
return $this->belongsTo('Comment');
}
}
My controller
public function imageViewer($id)
{
$images = Media::with(['comments' => function($query) {
$query->with('likes');
}])->where('resource_id', $id)->simplePaginate(1);
return View::make('image-viewer', compact('images'));
}
Why don't you just use blade's count like this count($comment->likes) assuming that $comment->likes gets the list of likes for a comment
#foreach ($images as image)
<img href="$image->url">
<div class="comment-box">
#foreach ($image->comments as $comment)
<div class="comment">
<span class="comment-owner">{{ $comment->owner()->name }}</span> {{ $comment->body }}
<div class="likes">
{{ count($comment->likes) }}
</div>
</div>
#endforeach
</div>
#endforeach
Thanks to #lukasgeiter for pointing out a mistake in the comments

Resources