Paginating in Laravel - php

I am working on an assignment for Uni however I've ran into a snag paginating my comments field. I have put my Controller, Model and View bellow(in that order)
<?php
namespace App\Http\Controllers;
use App\Comment;
use Illuminate\Http\Request;
class CommentController extends Controller
{
const COMMENTS_PER_PAGE = 5;
public function index () {
$comments = Comment::paginate (self::COMMENTS_PER_PAGE);
return view ('index') -> with (['comments' => $comments]);
}
public function create()
{
//
}
public function store(Request $request)
{
//
}
public function show(Comment $comment)
{
//
}
public function edit(Comment $comment)
{
//
}
public function update(Request $request, Comment $comment)
{
//
}
public function destroy(Comment $comment)
{
//
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
public static function paginate(int $COMMENTS_PER_PAGE)
{
}
}
{{--#extends('layout.master)--}}
{{--#section('content')--}}
<div class="container main-table">
<div class="box">
<h1 class="title">Guestbook Comments</h1>
#if (count ($comments) > 0)
<table class="table is-striped is-hoverable">
<thead>
<tr>
<th>User</th>
<th>Comment</th>
<th>Date</th>
<th>Likes</th>
</tr>
</thead>
<tbody>
#foreach ($comments as $c)
{{--declaring the comments--}}
<tr>
<td>{{ $c -> name }}</td>
<td>{{ $c -> comment }}</td>
<td>{{ $c -> created_at -> format ('D jS F') }}</td>
<td>{{ $c -> likes }}</td>
</tr>
#endforeach
</tbody>
</table>
{{--looking at pagination--}}
{{ $comments -> links() }}
#else
<div class="notification is-info">
<p>
The Guestbook is empty. Why not add a comment?
</p>
</div>
#endif
</div>
</div>
{{--#endsection--}}
I managed to get it to display the comments before changing to pagination. After doing this I ran into issues getting it to display. I don't get an error I just get a blank page as if nothing is wrong. It doesn't show any of my headings or text that is not from my comments table.
Has anyone got any ideas about why this is?
Any help would be greatly appreciated :D
Update 17:44 13/11/19
Just realised that the link was going to the wrong page but just now figured out that the count function is having and issue as it says that there is no relevant ARRAY ("Facade\Ignition\Exceptions\ViewException
count(): Parameter must be an array or an object that implements Countable (View: C:\XAMPP\htdocs\Assignment\resources\views\comment\comments.blade.php) ")
Does anyone know why this is?
I thought it would just list comments 1 by 1 up until it reads out 5 comments.
Any ideas on how to fix this? :)

change {{ $comments -> links() }} & try this
{!! $comments->render() !!}

I would recommend to paginate like this.
public function index () {
const COMMENTS_PER_PAGE = 5;
$comments = Comment::paginate(self::COMMENTS_PER_PAGE);
return view('index', compact('comments'))
->with('i', ($request->input('page', 1) - 1) * 5);
}
and also, change
{!! $comments->links() !!}
to
{!! $comments->render() !!}

{!! $comments->appends(Request::except('page'))->render() !!}

Related

Route Model Binding Problem Does Not Seem To Be Working

I'm working with Laravel 8 and I have made a table like this at Blade:
<div class="card-body table-responsive p-0">
<table class="table table-hover">
<tr>
<th>Username</th>
<th>Email</th>
<th>Role</th>
<th>Actions</th>
</tr>
#foreach($roles as $role)
#if(count($role->users))
#foreach($role->users as $user)
<tr>
<td>{{ $user->name }}</td>
<td>{{ $user->email }}</td>
<td>{{ $role->name }} | {{ $role->label }}</td>
<td>
<form action="{{ route('levels.destroy' ,$user->id) }}" method="post">
#method('DELETE')
#csrf
<div class="btn-group btn-group-xs">
Edit
<button type="submit" class="btn btn-danger">Delete</button>
</div>
</form>
</td>
</tr>
#endforeach
#endif
#endforeach
</table>
</div>
And the result perfectly showing up:
But now I got problem with Edit & Delete buttons that I have specified $user->id as parameter for both of them.
And when I hover over the buttons I can see the user id properly defined:
But when it comes to edit method which is using Route Model Binding, it does not find the user:
public function edit(User $user)
{
dd($user->id); // return null
}
However if I do not use Route Model Binding and say this instead:
public function edit($id)
{
dd($id); // return 1
}
It properly shows the user id!
I don't know why the Route Model Binding not working here, so if you know what's going wrong or how to fix this issue, please let me know...
You are trying to access the User Model which in this case doesn't know what id is, so you should be passing the id of the user to the edit route using either Get by passing it to the url endpoint , so now you can get it like
public function edit($id)
{
dd($id); // return null
}
or by sending it as a POST form and get it like
public function edit(Request $request)
{
dd($request->id); // return null
}
I saw comments, your resource controller name is not matching with your variable name "$user".
You can look here on official laravel docs.
In your situation, this might help;
Route::resource('levels', LevelController::class)->parameters([
'levels' => 'user'
]);

Paginate eager loaded relationships results

i am trying to paginate a relationship result set by using a code very similar to this
<?php
class MainController extends Controller {
public function show(Main $main)
{
$main = $main->with([
'secondaryMorph' => function ($query) {
$query->orderBy('ocurred_at');
$query->paginate(50);
}
])->first();
return view('main.show')->with(compact('main'));
}
}
But when this part of the view's code run a exception is thrown:
<td colspan="3">Mostrando {{ $secondary->count() }} de {{ $secondary->total() }}</td>
<td colspan="3">{{ $secondary->links() }}</td>
ErrorException (E_ERROR)
Method Illuminate\Database\Eloquent\Collection::total does not exist.
How can i use eager loading with pagination?
How about :
$main = $main->first();
$secondary = $main->secondaryMorph()->paginate();
return view('main.show')->with(compact('main','secondary'));
And then in blade :
<td colspan="3">Mostrando {{ $secondary->count() }} de {{ $secondary->total() }}</td>
<td colspan="3">{{ $secondary->links() }}</td>

Display unit count in Laravel blade template

I want to show total count of the unit so I wrote {{ ($unit->unit_id)->count() }} to return the data.
blade.php
<tbody>
#foreach($developer as $key => $data)
<tr>
<td></td>
<td>{{$data->developer_name}}</td>
<td>
#foreach($data->projects as $key => $project)
{{ $project->project_name }}<br>
#endforeach
</td>
<td>
#foreach($data->projects as $key => $project)
#foreach($project->phase as $key => $phase)
#foreach($phase->unit as $key => $unit)
{{ ($unit->unit_id)->count() }}<br> //error
#endforeach
#endforeach
#endforeach
</td>
</tr>
#endforeach
</tbody>
UPDATE:
Unit.php Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Unit extends Model
{
//
protected $table="pams_unit";
protected $primaryKey="unit_id";
}
UnitController
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Unit;
use App\Developer;
class UnitByDeveloperController extends Controller
{
//
public function __construct()
{
$this->middleware('auth');
}
public function show(Request $request){
$dev_id = $request->input('dev_id');
$developer =Developer::where(function($query1) use($dev_id){
if($dev_id){
$query1
->where('id',$dev_id);
}
})
->active()
->paginate('8');
return view('reportlayout.unitByDeveloper',compact('developer'));
}
}
But, an error is showing :-
Call to a member function count() on integer
Anyone can help me to spot my mistake ?
Change this:
{{ ($unit->unit_id)->count() }}
To:
{{ $unit->count() }}

Fetching data from Database in Laravel

I want to fetch data from database table named 'users' and display the output in a table.
I have written below code but it's not working.
I am using Laravel 5.5
#extends('layouts.app')
#section('content')
<div class="container">
<h2>Admin Panel</h2>
<p>Data of the Registered Users.</p>
<table class="table table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
$users = DB::table('users')->select('id','name','email')->get();
#foreach($users as $value)
<tr>
<td>{{ $value->id }}</td>
<td>{{ $value->name }}</td>
<td>{{ $value->email }}</td>
</tr>
#endforeach
</tbody>
</table>
</div>
#endsection
Error: Undefined Variable: users
The problem is that you're trying to mix PHP within your (Blade) template. Although it is possible to do so with #php directives, this is bad practice: your view should not contain any business logic.
Ideally you want to pass this data from your controller. It should look something like this:
use Illuminate\Support\Facades\DB;
class UserController extends Controller
{
public function index()
{
$users = DB::table('users')->select('id','name','email')->get();
return view('some-view')->with('users', $users);
}
}
Read more on passing data to views here.
You are doing it all wrong, the point of MVC design is to have your controllers do the application logic, your views to represent a representation of that data and models to contain the data you need, in your case you are missing the point completely by using DB::table inside of your view, so here is an example code which you might need to correct a bit:
The example below doesn't show MVC pattern since the data is passed from inside a closure of a route
web.php
Route::get('/', function () {
$users = DB::table('users')->select('id','name','email')->get();
return view('VIEW-NAME-HERE', compact('users'));
});
view.blade.php
#foreach($users as $user)
{{ $user->id }} {{ $user->name }} {{ $user->email }}
#endforeach
Change VIEW-NAME-HERE with the name of your view file, for example index or users.index
You Are using php in blade file
first make controller
for controller run a command in terminal
php artisan make:controller usercontroller
then write this:
class usercontroller extends Controller
{
public function index()
{
$users = DB::table('users')->select('id','name','email')->get();
$data = compact('users')
return view('your-view-name')->with('$data');
}
}

hasMany relationship Laravel 5.4 Trying to get property of non-object

I have a relationship in my models with foreing keys, protected table.
This is my models:
Lot.php:
<?php
namespace App;
class Lot extends Model
{
protected $table = 'auct_lots_full';
protected $primaryKey = 'lot_id';
public function comments()
{
return $this->hasMany(Comment::class,'lot_id', 'lot_id');
}
}
Than related model Comment.php:
<?php
namespace App;
class Comment extends Model
{
public function lot()
{
return $this->belongsTo(Lot::class, 'lot_id', 'lot_id');
}
}
In my view I try to do this:
#foreach ($comments as $comment)
<dt>{{ $comment->lot }}</td>
#endforeach
It result this:
{"lot_id":391959148,"date":"2017-05-21","company":"MITSUBISHI","model_year_en":2005"}
Than in view I need to get only company information and I do this:
#foreach ($comments as $comment)
<td> {{ $comment->lot->company }}</td>
#endforeach
this result Error:
Trying to get property of non-object
I try to do this:
#foreach ($comments as $comment)
<td>
#foreach($comment->lot as $lot)
{{ $lot->company }}
#endforeach
</td>
#endforeach
And it also gives error:
Trying to get property of non-object
How can I get $comment->lot->company work?
Thanks, to Snapey from laracasts
when you do this
#foreach ($comments as $comment)
<td> {{ $comment->lot->company }}</td>
#endforeach
you are relying on EVERY comment having a lot and every lot having a company
You can use this to protect against empty properties
#foreach ($comments as $comment)
<td> {{ $comment->lot->company or '---'}}</td>
#endforeach
Then the loop will continue even if the lot does not have company

Categories