Laravel 5.3 Eager Loading Selected Fields - laravel

I have this code:
$products = \App\Product::whereIn('id', $arrayKeys)
->with('photo')
->get();
And the result is:
If I use select code like this one:
$products = \App\Product::whereIn('id', $arrayKeys)
->select(['desc'])
->with('photo')
->get();
I can't see the photo. Is there a way to it? So that I can get the selected fields as well as the photo relationship.

Related

How to use with in Query Builder in laravel

I am trying to fetch data using slug between 2 table,
When I am using Eloquent then everything is fine but How to convert that query in Query Builder.
Eloquent Query :
$results = Product::orderBy('id','desc')->with('categories')->whereHas('categories', function ($query){
$query->where('slug', request()->sub_category);
})->paginate(24);
Here I am using two tables product and categories.
Query Builder :
$results = DB::table('products')
->leftJoin('wishlists', 'products.product_id', '=', 'wishlists.product_id')
->select('products.*', 'wishlists.wishlist_id', 'wishlists.user_id')
->with('menus')
->whereHas('categories', function ($query){
$query->where('slug', request()->category);
})
->orderBy('products.name', 'asc')
->paginate(24);
But here I am using 3 tables, Product, menu and Wishlist. Bcoz when user go to product page, I will highlight wishlisted product too.
Error :
Call to undefined method Illuminate\Database\Query\Builder::with()
You can use multiple with eloquent too,
try this
$results = Product::orderBy('id','desc')->with(['menus','categories' => function ($query){
$query->where('slug', request()->sub_category);
}])->paginate(24);

Laravel pagination with orderby doesnt work well

There's a problem about laravel paginate with orderby.
$products->with(['cover'])
->orderBy('priority', 'asc')
->paginate(12);
Code above returns different result then code below;
$products = $products->with(['cover'])
->orderBy('priority', 'asc')
->get();
All the first 12 records are different.
Whats wrong with it?

Product filtering problems with Laravel Query Builder

I try to implement ajax based filtering in my ecommerce project homepage for searching a product. I am using Laravel Query Builder. My Query for filtering products is given below-
$result= DB::table('products')
->leftjoin('products_description','products.products_id','products_description.products_id')
->leftjoin('image_categories', 'products.products_image', '=', 'image_categories.image_id')
->leftjoin('products_to_categories','products.products_id','products_to_categories.products_id')
->leftjoin('categories','products_to_categories.categories_id','categories.categories_id')
->when($category_slug, function($q) use ($category_slug) {
return $q->where('categories.categories_slug', $category_slug);
})
->where('products_name','like',"%{$querval}%")
->where('image_categories.image_type','=','ACTUAL')
->orderby('products.products_id','DESC')
->take(5)
->get();
I get every product twice in search result. don't know why. A sample response is given in this picture.
Can anyone help me to optimize my query for getting the desired result?
join with categories table only when you have to.
and select your columns strictly. then group by selected columns.
$result= DB::table('products')
->leftjoin('products_description','products.products_id','products_description.products_id')
->leftjoin('image_categories', 'products.products_image', '=', 'image_categories.image_id')
->when($category_slug, function($q) use ($category_slug) {
return $q->leftjoin('products_to_categories','products.products_id','products_to_categories.products_id')
->leftjoin('categories','products_to_categories.categories_id','categories.categories_id')
->where('categories.categories_slug', $category_slug);
})
->where('products_name','like',"%{$querval}%")
->where('image_categories.image_type','=','ACTUAL')
->orderby('products.products_id','DESC')
->select(['products_name','products.id','image_path'])
->groupBy(['products_name','products.id','image_path'])
->take(5)
->get();
you can use from groupBy to avoid comming repeated data.
try this one:
$result= DB::table('products')
->leftjoin('products_description','products.products_id','products_description.products_id')
->leftjoin('image_categories', 'products.products_image', '=', 'image_categories.image_id')
->when($category_slug, function($q) use ($category_slug) {
return $q->where('categories.categories_slug', $category_slug);
})
->where('products_name','like',"%{$querval}%")
->where('image_categories.image_type','=','ACTUAL')
->orderby('products.products_id','DESC')
->groupBy('products_name','products.products_id')
->take(5)
->get();

Convert Query Builder to Eloquent

I have these tables:
products: id, name
orders: id, number
order_items: order_id, product_id
So I want to get best order products. And i make this code below.
$sales = DB::table('products')
->leftJoin('order_items','products.id','=','order_items.product_id')
->leftJoin('orders','orders.id','=','order_items.order_id')
->selectRaw('products.*, COALESCE(sum(orders.item_count),0) total')
->groupBy('products.id')
->orderBy('total','desc')
->take(6)
->get();
Please help me convert query above to eloquent. This work but I want to get products morphed images too.
Eloquent also support leftJoin, so you can do something like this:
$sales = Product::query()
->leftJoin('order_items','products.id','=','order_items.product_id')
->leftJoin('orders','orders.id','=','order_items.order_id')
->selectRaw('products.*, COALESCE(sum(orders.item_count),0) total')
->groupBy('products.id')
->orderBy('total','desc')
->take(6)
->get();
But if you mean you want to use eager load, please share your models and these relations first,
Assuming you created proper relationships in the Product model, would look something like this:
Product::with('order_items', 'orders')
->selectRaw('COALESCE(sum(orders.item_count),0) as total')
->orderByDesc('total')
->limit(6)
->get();

Counting data before sending to view in Laravel

I have two tables, products and product_images, now I want to show product which has at least one image.
In controller I have a simple function in ProductController to fetch all the products:
public function products(){
$allProducts = $this->product->paginate(15);
return view('frontend.pages.products',compact('allProducts'));
}
But, I want to send the products which has at least one image of each product.
What should I do to achieve that?
Edit:
I have created relationship between tables, now how can I get my desired answer?
I have written this in the Controller:
$allProducts = $this->product->whereHas('product_images', function ($query){
$query->where();
})->get();
Assuming table schema
product
-id
-name
product_image
-id
-product_id
-url //any columns you needed
$product_ids = DB::table('product')
->join('product_image','product_image.product_id','=','product.id')
->select('product.id','roduct.name')
->groupBy('product.id')
->get();
$product_count = count($product_ids);
Eloquent has this built in.
Example
// Retrieve all posts that have three or more comments...
$posts = App\Post::has('comments', '>=', 3)->get();
In your case
In your case you could change the $allProducts line to be
$allProducts = $this->product()->has('product_image', '>=', 1)->paginate(15);
I didn't test the code above.
See documentation for more information on this topic.
https://laravel.com/docs/6.x/eloquent-relationships#querying-relationship-existence
You can use selectRaw:
$products = Product::leftJoin('product_images',function ($join){
$join->on('products.product_id','=','product_images.product_id');
})->selectRaw("products.product_id i, count(product_images.id) c")
->groupBy('products.product_id')
->where('c','>=',3)
->get();
Getting answer querying realtionship:
The query will look like following:
$allProducts = $this->product->has('Images')->paginate(15);
But, make you sure you have created relation in Model like the following:
public function Images(){
return $this->hasMany('\App\Models\ProductImages');
}
I have used hasMany relationship because one product can have multiple images.

Resources