Laravel Pagination with eloquent Queries - laravel-4

I am trying to paginate my template which has a table on it.
This is my function in the controller which has the eloquent queries.
public function orderbydate()
{
$order =DB::table('sales_flat_order_items as s')
->leftJoin('sales_flat_orders as w', 'w.entity_id','=','s.order_id')
->select(array(DB::Raw('sum(s.amount_refunded) as amount_refunded'),
DB::Raw('sum(s.row_total) as row_total'),
DB::Raw('sum(s.discount_amount) as discount_amount'),
DB::Raw('sum(s.tax_amount) as tax_amount'),
DB::Raw('sum(s.qty_ordered) as qty_ordered'),
DB::Raw('sum(w.subtotal) as subtotal'),
DB::Raw('sum(w.total_invoiced) as total_invoiced'),
DB::Raw('sum(w.shipping_amount) as shipping_amount')))
->where('qty_canceled','=','0')
->where('status','!=','canceled')
->get();
$orderbydate = DB::table('sales_flat_order_items as s')
->leftJoin('sales_flat_orders as w', 'w.entity_id','=','s.order_id')
->select(array(DB::Raw('sum(s.amount_refunded) as amount_refunded'),
DB::Raw('sum(s.row_total) as row_total'),
DB::Raw('sum(s.discount_amount) as discount_amount'),
DB::Raw('sum(s.tax_amount) as tax_amount'),
DB::Raw('sum(s.qty_ordered) as qty_ordered'),
DB::Raw('sum(w.subtotal) as subtotal'),
DB::Raw('DATE(w.created_at) days'),
DB::Raw('sum(w.total_invoiced) as total_invoiced'),
DB::Raw('sum(w.shipping_amount) as shipping_amount')))
->where('qty_canceled','=','0')
->where('status','!=','canceled')
->groupBy('days')
->orderBy('s.created_at')
->get();
return View::make('sales_flat_orders.orderbydate', compact('order','orderbydate'), ['orderbydate'=>Paginate(3)]);
}
I want to use pagination in my template. So i ma doing like this.
#foreach(array_chunk($orderbydate->getCollection()->all(), 3) as $row)
<div class = "row">
#foreach($row as $s)
<article class = "col-md-4">
<tbody>
<tr class="odd gradeX">
<td>{{date("d F, Y",strtotime($s->days))}}</td>
<td>{{ round($s->qty_ordered, 2) }}</td>
<td>{{round($s->subtotal,2)}}</td>
<td>{{round($s->tax_amount,2)}}</td>
<td>{{round($s->discount_amount,2)}}</td>
<td>{{round($s->row_total,2)}}</td>
<td>{{round($s->amount_refunded,2)}}</td>
<td>{{round($s->total_invoiced,2)}}</td>
<td>{{round($s->shipping_amount,2)}}</td>
</tr>
</article>
#endforeach
#endforeach
But thins does not work. Where am i going wrong?
Thanks in advance

If you want to use pagination instead of get method you need to use paginate method.
For example the working pagination should work like this:
Paginator::setCurrentPage($page);
Paginator::setBaseUrl($baseUrl);
Paginator::setPageName('page');
$users = User::paginate(15);
now in Blade template you can display users in foreach loop and add pagination links:
#foreach ($users as $user)
{{{ $user->name }}}
#endforeach
{{ $users->links() }}
You should definitely look also at Pagination documentation

Related

Undefined property: Illuminate\Database\Eloquent\Relations\BelongsToMany::$path

I wrote a relation belongsToMany between products and photos and now I want to show products in the home page. I did it like so:
#foreach ($latestProducts as $product)
<img src="{{$product->photos()->path}}">
#endforeach
homeController:
public function index()
{
$latestProducts = Product::orderBy('created_at' , 'desc')->limit(10)->get();
return view('front.layouts.index' , compact('latestProducts'));
}
photo model:
public function products() {
return $this->belongsToMany(Product::class);
}
product model:
public function photos() {
return $this->belongsToMany(Photo::class);
}
I got Undefined property: Illuminate\Database\Eloquent\Relations\BelongsToMany::$path .And when I write {{$product->photos[0]->path}} , the error changes to "Undefined array key 0. Also when I write {{$product->photos->path}} ,I get an error as "Property [path] does not exist on this collection instance."
I believe you got a photo attribute/field in the Photo model. Because photos is a collection of photos, you might want to write:
#foreach ($latestProducts as $product)
#foreach ($product->photos as $photo)
<img src="{{$photo->path}}">
#endforeach
#endforeach
And only the first photo:
#foreach ($latestProducts as $product)
<img src="{{$product->photos->first()->path}}">
#endforeach
// Or to be safe
#foreach ($latestProducts as $product)
<img src="{{optional($product->photos->first())->path}}">
#endforeach
// Or this in php 8
#foreach ($latestProducts as $product)
<img src="{{$product->photos->first()?->path}}">
#endforeach
You have to use
{{ $product->photos->path }}
cause when you deal with relations in blade you deal with it as a property of class of the father class unlike when you deal with it in eloquent ORM you can use photos()
Basically the error is saying that there is no property photos in the $products. Assuming that the table name is correct and the foreign keys too
you can just do:
public function index()
{
$latestProducts = Product::with('photos')->orderBy('created_at' , 'desc')->limit(10)->get();
return view('front.layouts.index' , compact('latestProducts'));
}
And in blade file try to remove the (), because it will load the relationship.
#foreach ($latestProducts->photos as $product)
<img src="{{$product->path}}">
#endforeach

Laravel blade echo the value doesn't work

I have two tables ..
User and UserMeta
I made relationship between them with hasOne().
Model
public function user_meta() {
return $this->hasOne('App\UserMeta');
}
Controller
public function index() {
$users = User::orderBy('id', 'desc')->paginate(10);
return view('users.index')->with('users', $users);
}
View
#forelse ($users as $user)
{{ $user->user_meta->country }}
#empty
#endforelse
This return error
Trying to get property 'country' of non-object
But here if I use dd() like this.
#forelse ($users as $user)
{{ dd($user->user_meta->country) }}
#empty
#endforelse
I can see the value return correctly. United State
dd stop loop execution for first element. If you uses dump helper, you will see this error again after several iterations. You need check for null:
#forelse ($users as $user)
#if(!is_null($user->user_meta))
{{ $user->user_meta->country }}
#endif
#empty
#endforelse

Make a sum() of column accessors Laravel

im improving my skills in laravel making a simple challenges web but i stuck on the next problem.
I have the users table with the id, name, mail, etc. The challenges table where i list all the challenges (with columns id, name, body, answer, score) and a third table called "Answers" where i post each try of the users solving a challenge with the columns id, user_id, challenge_id, success (boolean) and score.
Now i'am trying to make a ranking of users with their scores. The problem is to show a sum() of the column 'score' in the table answers where user_id.answers = users.id. So i can get easy the total score for each user.
For now i solved the problem doing this in blade:
#foreach($users as $user)
<tr>
<th>{{ $user->id }}</th>
<td>{{ $user->name }}</td>
<td>Team pindonga</td>
<td>{{ score = DB::table('answers')->where('user_id', $user->id)->sum('score') }} </td> </tr>
#endforeach
works perfectly, but i want to get them by desc score (for now i solved the desc with js but want to get desc order from the eloquent query) and have something like this in the blade:
#foreach($users as $user)
<tr>
<th>{{ $user->id }}</th>
<td>{{ $user->name }}</td>
<td>Team pindonga</td>
<td>{{ $team->score }} </td> </tr>
#endforeach
I was thinking about solve it with accessors doing something like this:
public function getScoreAttribute($value)
{
return $this->groupBy('user_id')->where('user_id', '=', $value)->sum('score');
}
also i have a relationship belongsTo in the answers modle to users and a hasMany in the users to answers. But i'm not sure of how pass the results to blade. Tried in tinker:
>>> \App\Answer::find(1)->score;
=> "3400"
>>> \App\Answer::find(2)->score;
=> "3400"
>>> \App\Answer::find(5)->score;
=> "3400"
allways getting the sum of the id = 1. And with $user->score; in the blade foreach i got a '0'.
Using the relationship with Blade would be {{ $user->answers->sum('score') }}. No accessor needed.
For sorting I would use the sortByDesc collection method.
$users = User::get();
$users = $users->sortByDesc(function ($user) {
return $user->answers->sum('score');
});
I think this is what you're looking for. It takes a while to get used to Eloquent ORM :-)
foreach($users as $user){
print $user->answers->sum('score');
}
https://laravel.com/docs/5.6/queries#aggregates

Display Fields of Relationship Query in Blade

After binding tables in a model and writing a query, fetched data in a Blade shows error.
Trying to get property of non-object
Model
<?php
public function unit()
{
return $this->belongsTo('TEST\Units');
}
Query
$inst = Instructions::with('unit')
->where('id',$inst_id)
->first()
->get();
Model
#foreach ($inst as $item)
<pre>{{$item->units->name}}</pre>
#endforeach
However, when using this code and I delete a name or other field, no error displays...
#foreach ($inst as $item)
<pre>{{$item->units}}</pre>
#endforeach
output:
{"id":1,"name":"UNIT 101","description":null,"created_at":"2017-03-06 13:30:18","updated_at":"2017-03-06 13:30:18"}
Solved
#foreach ($inst as $item)
#if (!empty($item->unit->id))
<pre>{{$item->unit->name}}</pre>
#endif
#endforeach

Pagination in laravel 5 with realtion on where condition

Model smsHeader
protected $fillable = [
'type',
'imei',
'login',
'ver'
];
public function detail()
{
return $this->hasMany('App\Model\smsDetail', 'id_header');
}
Controller
$smsheader = smsHeader::orderBy('id', 'desc')->where('login', $user->email)->paginate(20);
return view('app.inbox')->with('smsheader', $smsheader);
Views
#foreach($smsheader as $header)
#foreach($header->detail->where('type', '1') as $detail)
<tr>
<td>{{$detail->number}}</td>
<td>{{$detail->name}}</td>
<td>{{$detail->text}}</td>
<td>{{$detail->date}}</td>
</tr>
#endforeach
#endforeach
but the result of pagination it was error, how i can set paginition in where smsdetail condition....??
sorry for my bad english
The error is showing for this line $header->detail->where('type', '1')
you can access $header->detail within foreach if you want to use where condition then you need to use get() at the end,like below
#foreach($smsheader as $header)
#foreach($header->detail->where('type', '1')->get() as $detail)
<tr>
<td>{{$detail->number}}</td>
<td>{{$detail->name}}</td>
<td>{{$detail->text}}</td>
<td>{{$detail->date}}</td>
</tr>
#endforeach
#endforeach
Laravel Queries within Blade views do not automatically execute. They simply prepare another QueryBuilder instance. You still need to run one of the "execute" methods (that will run PDOStatement::execute() underneath). These methods are:
first() (returns first result from result set as single object)
get() (which returns a Collection (ArrayObject with some added extra functionality))
paginate($numberPerPage) (which returns a Collection with extra meta information to pass to a $links property accessible via $collection->links())
In your example:
#foreach($smsheader as $header)
#foreach($header->detail->where('type', '1')->get() as $detail)
<tr>
<td>{{$detail->number}}</td>
<td>{{$detail->name}}</td>
<td>{{$detail->text}}</td>
<td>{{$detail->date}}</td>
</tr>
#endforeach
#endforeach

Resources