how to use pangination and sortByDesc fuction in laravel? - php

i tried to use pagination in my laravel view i got this problem
Method Illuminate\Database\Eloquent\Collection::links does not exist. (View: C:\wamp\www\project\resources\views\demmande\demmandes.blade.php)
here is my controller function
public function ViewDemmandes(){
$listdemmande=Demmande::paginate(10)->sortByDesc('created_at');
$listvillee=Ville::all();
$listcategorie=Categorie::all();
$villes = $listvillee;
$demmande = $listdemmande;
$categorie = $listcategorie;
return view("demmande.demmandes",compact('villes','categorie','demmande'));
}
but when i delete sortByDesc function like this
public function ViewDemmandes(){
$listdemmande=Demmande::paginate(3);
$listvillee=Ville::all();
$listcategorie=Categorie::all();
$villes = $listvillee;
$demmande = $listdemmande;
$categorie = $listcategorie;
return view("demmande.demmandes",compact('villes','categorie','demmande'));
}
it works fine please can you help me resolve this problem

The ->paginate(10) will return an instance of LengthAwarePaginator. Which implements all the methods the Collection has (->sortByDesc() being one of them). But calling a collection method will return the underlying collection, not an instance of paginator.
So in your case you're overriding the paginator with the collection being returned from ->sortByDesc().
Sort with SQL instead of on a collection:
$listdemmande = Demmande::orderBy('created_at', 'DESC')->paginate(10);
// Or using `->latest()` shorthand:
// $listdemmande = Demmande::latest()->paginate(10);
If there's a reason why you want to sort after fetching the query, you could override just the paginators underlying collection:
$listdemmande = Demmande::paginate(10);
$listdemmande->setCollection($listdemmande->sortByDesc('created_at'));

You can use like this in controller
$listdemmande=Demmande::orderBy('created_at', 'desc')->paginate(10);
And also don't forget to add in blade view to add this ...
After foreach add to this
{{$listdemmande->links()}}
Your links error is solve.

Related

Foreach with eloquent in laravel

I'm trying to loop through the items using eloquent in laravel but I'm getting 0. Please see my code below.
Model
Class Store{
public function products(){
return $this->hasMany('App\Product');
}
}
Controller
$products_count = 0;
foreach($store->products() as $product)
{
if($product->status == 1)
{
$products_count++;
}
}
dd($products_count);
Note: I have data in my database.
You can also use withCount method something like that
Controller
$stores = Store::withCount('products')->get();
or
$store = Store::where('id', 1)->withCount('products')->first();
WithCount on the particular status
$stores = Store::withCount(['products' => function ($query) {
$query->where('status', 1);
}
])
->get();
ref: withcount on relationship
That's because $store->products() returns an eloquent collection which doesn't contain the data from the database yet. You need to do $store->products instead.
If you need to get the count from the database then use
$store->products()->where('status', 1)->count()
With the function-annotation (i.e. products()) you are retrieving the \Illuminate\Database\Eloquent\Builder-instance, not the actual Eloquent-collection.
Instead, you would have to use $store->products – then you will get retrieve the related collection.
In Laravel $store->products() makes you access the QueryBuilder instance, instead there is the Laravel way of doing $store->products, which loads the QueryBuilder and retrieves the collection automatically and down the line is easy to optimise.

Return json with data from three tables in Laravel

//CartController
$itens = CartItem::where('id_cart', $cart->id)->with('product')->get();
return response()->json($itens);
This code returns a JSON with the data of the cart item and the relative product. But I also want to return the images of the product, which is in the ProductImages table.
In my model CartItem.php I have
public function product(){
return $this->belongsTo('App\Product', 'id_product');
}
In my model Product.php I have
public function images(){
return $this->hasMany('App\ProductImages', 'id_product');
}
But, if I do
$itens = CartItem::where('id_cart', $carrinho->id)->with('product')->with('image')->get();
I get the error
Call to undefined relationship [images] on model [App\CartItem]
You can try it as:
CartItem::where('id_cart', $carrinho->id)->with('product.images')->get();
To eager load nested relationships, you may use "dot" syntax.
Docs
You should load two tables by using with():
CartItem::where('id_cart', $cart->id)
->with('product', 'product.images')
->get();
You can read an explanation here (see Nested Eager Loading section).
you should make use of the nested eager load function:
$books = App\Book::with('author.contacts')->get();
https://laravel.com/docs/5.3/eloquent-relationships#eager-loading
Just use like this
$itens = CartItem::where('id_cart', $carrinho->id)->with('product','images')->get();

Laravel query builder returns object or array?

I'm building a very simple web app with Laravel.
I've built two separate Controllers, which each return two separate views, as follows:
ProfileController:
class ProfileController extends BaseController {
public function user($name)
{
$user = User::where('name', '=', $name);
if ($user->count())
{
$user = $user->first();
$workout = DB::table('workouts')->where('user_id', '=', $user->id)->get();
Return View::make('profile')
->with('user', $user)
->with('workout', $workout);
}
return App::abort(404);
}
}
WorkoutController:
class WorkoutController extends BaseController {
public function workout($name)
{
$workout = DB::table('workouts')->where('name', '=', $name)->first();
if ($workout)
{
Return View::make('add-exercise')
->with('workout', $workout);
}
return App::abort(404);
}
}
What is confusing me is what I had to do in order to pass a single workout object to each view. As you might have noticed the query builders for workout are different:
$workout = DB::table('workouts')->where('user_id', '=', $user->id)->get();
and
$workout = DB::table('workouts')->where('name', '=', $name)->first();
On the profile view, I get an object using the ->get(); method, but on the add-exercise view, I must use ->first(); or I will otherwise get an array with only one index, where I can then access the object, i.e. $workout[0]->name instead of $workout->name.
Why is this? Shouldn't I be able to use either get and/or first in both controllers and expect the same type of result from both since I want the same thing from the same table?
get() returns a collection of objects every time. That collection may have 0 or more objects in it, depending on the results of the query.
first() calls get() under the hood, but instead of returning the collection of results, it returns the first entry in the collection (if there is one).
Which method you use depends on what you need. Do you need the collection of all the results (use get()), or do you just want the first result in the collection (use first())?
Model::find(numeric); returns a object
Model::whereId(numeric)->first(); returns a object
Model::whereId(numeric)->get(); - returns a collection
Model::whereId(numeric); - returns a builder

Laravel 4 model method failed with "Call to undefined method"

My models extends "\BaseModel" which in its turn extends the Eloquent.
class BaseModel extends Eloquent {
public function foo($attribute)
{
//some code
}
In my collection, where the model being instanced I'm trying to access the "foo()" method, but it responses me with "Call to undefined method".
$data = IncomeDoc::with('details')
->where('type', '!=', 2)
->get();
$data = $data->foo();
Moreover, I tried to place the method "foo" in the model itself, but there was no difference.
Thanks for all
Basically get() method returns a Collection of instances. Assume more than 1 model satisfy type != 2 condition. If you want to get first model under the condition just use first() instead.
$data = IncomeDoc::with('details')
->where('type', '!=', 2)
->first();
$data = $data->foo();
Otherwise:
$collection = IncomeDoc::with('details')
->where('type', '!=', 2)
->get();
$data = [];
foreach($collection as $item) {
$data[] = $data->foo();
}
Actually get() returns a collection, an instance of Illuminate\Database\Eloquent\Collection and in this collection there is no foo method but to call the method that you declared in your model, you need to access the model, so first model in the collection would be 0 and to get it you may use $data->first() or $data->get(0), to get the second item (model) from the collection you may use $data->get(1) and so on but you may also use a loop, for example:
$data = IncomeDoc::with('details')->where('type', '!=', 2)->get();
$dataArray = array();
$data->each(function($item) use (&$dataArray){
$dataArray[] = $item->foo();
});
return View::make('viewname')->with('data', $dataArray);
Also, you may directly pass the $data to your view and can apply the function call from the view within a loop but not recommended.

Paging in PHP Laravel

I am trying to make a paging in Laravel, but i keep getting errors.
I try put
->paginate(3)
On the return, but i keep getting errors like Call to undefined method Laravel\Paginator::get() and Call to undefined method Laravel\Paginator::order_by()
public function get_index()
{
$categories = Category::all();
return View::make("stories.index")
->with("title","Sexnoveller")
->with("categories", $categories)
->with("stories", DB::table('stories')
->order_by('id', 'desc')->get());
}
To use pagination call paginate() instead of get(). In your case that would be:
return View::make("stories.index")
// ...
->with("stories", DB::table('stories')
->order_by('id', 'desc')->paginate(3));
Then in the view just remember to iterate over $stories->results.
I do recommend to create a model for that Stories table. Once done, you could do something like:
Story::orderby('story_name', 'ASC')->paginate(10);

Categories