Get related products for a product by category - laravel

I'm trying to show products related to a category. But it is showing all products which are also related to other categories.
Blade:
<div class="row">
#foreach($categories as $category)
#foreach ($category->products as $product)
<div class="col-sm-12 col-md-6 col-lg-4 p-b-50">
<!-- Block2 -->
<div class="block2">
<div class="block2-img wrap-pic-w of-hidden pos-relative block2-labelnew">
<img src="{{ URL::to('/') }}/images/backend_images/product_images/{{ $product->product_image }}"
class="img-thumbnail" style="width: 270px; height: 360px;" />
<div class="block2-overlay trans-0-4">
</div>
</div>
<div class="block2-txt p-t-20">
<a href="product-detail.html" class="block2-name dis-block s-text3 p-b-5">
{{ $product->product_name }}
</a>
<span class="block2-price m-text6 p-r-5">
$75.00
</span>
</div>
</div>
</div>
#endforeach
#endforeach
</div>
Controller:
public function products(Request $request, Product $product)
{
$categories = Category::with('products')->distinct()->get();
return view('product.listing', compact('product', 'categories'));
}
Route:
Route::get('/product/{id}','Admin\ProductController#products')->name('product.products');

Edit your controller:
public function products(Request $request, Product $product)
{
$categories = $product->categories;
return view('product.listing', compact('product', 'categories'));
}
Also you should have the categories relationship method on Product Model.

public function products(Request $request, Category $category)
{
$products = Product::where('category_id',$category->id)->get();
$categories = Category:all();
return view('product.listing', compact('products','categories'));
}

Your route is
Route::get('/product/{id}','Admin\ProductController#products')->name('product.products');
//{id} it means you're getting category id from route right? so you can directly access it in controller.
Controller
//$id is from route.
public function products($id)
{
$products = Product::with('category')->where('category_id',$id)->get();
return view('product.listing', compact('products'));
}
In your blade file
#foreach($products as $product)
//here your all product which belongs to that categories.
and now if you want to access categories then may do as.
categories :- {{ $product->category->name }} //make sure it belongsTo in product
#endforech

public function products(Request $request)
{
$categories = Category::where('id',$request->id)->with('products')->get();
return view('product.listing', compact('categories'));
}
#foreach($categories as $category)
#foreach ($category as $product)

Assuming a product has one category and you have a category_id column in your products table change products method in your ProductController like below.
public function products(Request $request, Product $product)
{
$relatedProducts = Product::where('category_id', $product->category_id)
->where('id', '!=', $product->id) // ignore current product
->get();
return view('product.listing', compact('product', 'relatedProducts'));
}
Replace id in your route withproduct`. Read More about route model binding.
Route::get('/product/{product}','Admin\ProductController#products')->name('product.products');
Then in your view your you can iterate through relatedProducts

controller:
public function products(Request $request, Category $category)
{
$category->load('products');
return view('product.listing', compact('category'));
}
route:
Route::get('/product/{category}','Admin\ProductController#products')->name('product.products');
blade file:
#foreach ($category->products as $product)
<div class="col-sm-12 col-md-6 col-lg-4 p-b-50">
<!-- Block2 -->
<div class="block2">
<div class="block2-img wrap-pic-w of-hidden pos-relative block2-labelnew">
<img src="{{ URL::to('/') }}/images/backend_images/product_images/{{ $product->product_image }}" class="img-thumbnail" style="width: 270px; height: 360px;" />
</div>
</div>
</div>
#endforeach

Related

I want items to be under the category they are related to

I want to achieve this result, but I can't understand the logic of the sql implementation
here is my welcome.blade.php:
#extends('layouts/layout')
#section('content')
<div class="container-fluid">
#foreach ($categories as $category)
<h4>{{$category->category_name}}</h4>
<div class="row">
<div class="col-sm-4">
<h6>{{$category->item_name}}</h6>
</div>
</div>
#endforeach
</div>
#endsection
and my controller:
$categories = DB::table('items')
->join('categories', 'items.category_id', 'categories.id')
->select('items.item_name', 'items.item_price', 'categories.category_name', 'categories.description')
->groupBy('categories.category_name')
->get();
return view('welcome', 'categories'=> $categories]);
You can use the QueryBuilder here if you want, but I would suggest using Eloquent unless you have a particular reason to not use it.
Let's assume that you have a Category and Item model and that you've defined a relational function within the Category model back to the Item model.
class Category extends Model
{
public function items()
{
// this assumes you're using standard naming conventions
return $this->hasMany(Item::class);
}
}
Then in your Controller, you might do something like the following to obtain categories and their related items.
$categories = Category::with('items')->get();
return view('welcome', compact('categories'));
The above can be adapted when required to limit the query to a specific Category when you require it. We use the with method to eager load the related records so that we can avoid the n+1 query problem.
Finally, in your view you can iterate (loop) over the categories and loop over the related items (there could be more than one).
#forelse($categories as $category)
<h4>{{ $category->category_name }}</h4>
#forelse ($category->items as $item)
<p>{{ $item->item_name }}</p>
#empty
<p>No items</p>
#endforelse
#empty
<p>No results</p>
#endforelse
The above is purely illustrative and ideally, you would break the above into reusable components.
Since you're using Laravel, you could use Eloquent relationships:
class Category extends Model{
public function items{
return $this->hasMany(Item::class);
}
}
Then in your controller:
$categories = Category::with('items')->get();
return view('welcome', ['categories'=> $categories]);
Then in your view:
#foreach ($categories as $category)
<h4>{{$category->category_name}}</h4>
#foreach($category->items as item)
<div class="row">
<div class="col-sm-4">
<h6>{{$item->name}}</h6>
</div>
</div>
#endforeach
#endforeach
$categories = DB::table("categories")->select("id", "category_name", "description")->get();
$items = DB::table("items")->select("category_id", "item_name", "price")->get();
view('welcome',compact("categories", "items"));
/////////////////////// BLADE ///////////////////////
<div class="container-fluid">
#foreach ($categories as $category)
#foreach($items as $item)
#if($category->id === $item->category_id)
<h4>{{$category->category_name}}</h4>
<div class="row">
<div class="col-sm-4">
<h6>{{$category->item_name}}</h6>
</div>
</div>
#endif
#endforeach
#endforeach
</div>
Try this.

Laravel Categories, Subcategories and model binding

I have two tables: products and categories. Every product have specific category.
The products table has category_id.
The categories table has name and parent_id.
This is my example product: iPhone 12.
In the admin section I have category Apple and subcategory iPhone and then I put the product (iPhone 12) inside the subcategory iPhone.
In the frontend section I can successfully display the category tree unordered list and when I click on the subcategory iPhone, the product iPhone 12 displays fine but when I click on the category Apple, the product doesn't show. How can I display the data from the parent, so when I click on Apple category or iPhone subcategory to display the product in both cases?
Here's my code:
Model category
public function products()
{
return $this->hasMany('App\Models\Product');
}
public function children() {
return $this->hasMany('App\Models\Category', 'parent_id');
}
Category model
public function products()
{
return $this->hasMany('App\Models\Product');
}
ProductController
public function productCategory(Category $category) {
$categories = Category::with('children')->whereNull('parent_id')->where('status',1)->get();
$products = $category->products;
return view('products', compact('products', 'categories'));
}
Route
Route::get('/category/{category:slug}', 'App\Http\Controllers\ProductController#productCategory')->name('product.category');
Products view:
<div class="content products">
<div class="container">
<div class="row">
<div class="col-md-3">
<div class="categories">
<ul>
#foreach($categories as $category)
<li>
{{ $category->name }}
#if($category->children)
<ul>
#foreach($category->children as $child)
<li>
{{ $child->name }}
</li>
#endforeach
</ul>
#endif
</li>
#endforeach
</ul>
</div>
</div>
<div class="col-md-9">
<div class="row">
#foreach($products as $product)
<div class="col-sm-4">
<div class="image">
<img class="img-fluid" src="{{ Storage::url($product->image) }}" />
</div>
<div class="title">
<h3>{{ $product->title }}</h3>
</div>
</div>
#endforeach
</div>
</div>
</div>
</div>
</div>
I think you could use hasManyThrough function provided by laravel
In the category model add these functions
//retrunt only the subcategories of the category
public function subcategories()
{
return $this->hasMany(Category::class,'parent_id');
}
//return the products directly by the parent category
public function categotyProducts()
{
return $this->hasManyThrough(
Product::class,
category::class,
'parent_id',
'category_id',
);
}
for more information see the docs
Hope that works for you!
In your Product model define category relationship as below.
public function category()
{
return $this->belongsTo('App\Models\Category','category_id');
}
In your controller function define slug variable and use below query to get Products
$slug = ($category->slug)??'';
Query for products:
$products = Product::where(function($query) use ($slug){
$query->whereHas('category',function($q) use ($slug){
$q->where('name', 'like', '%' . $slug . '%');
})
->orWhereHas('category.children',function($q) use ($slug){
$q->where('name', 'like', '%' . $slug . '%');
});
})->get();

list of products in an foreach with an foreach

For school I got a project to make an webshop so I try to make an admin dashboard where if u wanna see the users informatie, u also will see the orders the user placed.
Right now i try this
#foreach($user->order as $order)
<div class='col-sm-12 col-md-6 col-lg-6'>
<div class="card">
<div class="card-header">
<b>Order ID:</b> {{ $order->id }}
</div>
<div class="card-body">
<ul class="list-group list-group-flush">
<li class="list-group-item list-group-item-secondary text-center text-danger"><b>Info:</b></li>
<li class="list-group-item"><b>Datum:</b> {{ $order->date }}</li>
<li class="list-group-item"><b>Prijs:</b> € 200</li>
<li class="list-group-item list-group-item-secondary text-center text-danger"><b>Producten:</b></li>
#foreach($user->order->orderrow as $orderrow)
<li class="list-group-item">{{ $orderrow->product->productname }}</li>
#endforeach
</ul>
</div>
</div>
</div>
#endforeach
but how can i make it that when i want to see the orderrow from an other table then the order table. is able to be worked in an foreach on the users.show.blade.php
Product model
public function orderrows()
{
return $this->hasMany(Orderrow::class)->orderBy('date', 'desc');
}
Orderrow model
public function product()
{
return $this->belongsTo(Product::class);
}
Order model
public function user()
{
return $this->belongsTo(User::class);
}
public function orderrow()
{
return $this->hasMany(Orderrow::class);
}
User model
public function order()
{
return $this->hasMany(Order::class);
}
Try using this code for inner foreach loop.
#foreach($order->orderrow as $orderrow)
<li class="list-group-item">{{ $orderrow->product->productname }}</li>
#endforeach

Laravel filter results with dropdown menu

I am showing abstracts from my database and I want to filter them using drop-down menu.
I have already created the drop-down menu with the categories which are Medicine and Nursing
my view which includes the drop-down menu
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" data-
toggle="dropdown" value="">Show all</button>
<ul class="dropdown-menu" role="menu">
#foreach ($schools as $school)
<li value="{{ $school->id }}">{{ $school->School_Type }}</li>
#endforeach
</ul>
</div>
My controller
public function index(Request $request)
{
$schools = School::all();
$items = $request->items ?? 5; // get the pagination number or a default
$abstracts = Project::orderBy('A_ID','asc')->paginate($items);
return view ('Abstracts.index')->with ('abstracts', $abstracts)
->withItems($items)
->with('schools',$schools);
}
can someone guide how to route it properly
I'd do it like this:
public function index(Request $request)
{
$schools = School::all();
$items = $request->items ?? 5; // get the pagination number or a default
$abstracts = Project::orderBy('A_ID','asc')->paginate($items);
return view ('Abstracts.index')->with([
'abstracts' => $abstracts,
'items' => $items,
'schools' => $schools
]);
}
And in your view, you can confirm it like:
#foreach ($schools as $school)
{{ $school }}
#endforeach

Laravel search not returning any result

I am trying to create a search where user can search for book title. There is a field in 'books' table called 'title'.
however if I do dd($books); I get:
Collection {#667 ▼
#items: []
}
If I do dd($searchTerms); output seems to be correct
Here's my controller:
function search()
{
$books = Book::all();
return view('layouts/search',['books' => $books]);
}
function details() {
$searchTerms = explode(' ', \Request::input('book'));
$books = Book::where(function($q) use($searchTerms) {
foreach ($searchTerms as $book) {
$q->orWhere('title', '%'.$book.'%');
}
})->get();
dd($books);
return view('layouts/details', compact('books'));
}
Search blade:
#extends('layouts.master')
#section('title')
#section('content')
<h1>Search for books</h1>
<form action="{{url('details')}}" method="POST">
{{ csrf_field() }}
<div>
<input type='text' name='book' placeholder='Enter any character' />
</div>
<input type="submit" name="submitBtn" value="Search">
</form>
#endsection
Details blade:
#extends('layouts.master')
#section('title')
#section('content')
<h1>User Details</h1>
<form>
<p>
<ul>
#foreach ($books as $book)
<a href= "{{url('reader/'.$book->title)}}">
{{$book->title}}</a>
</p>
</form>
#endforeach
</ul>
#endsection
You forgot to tell the eloquent builder that your OR's should have LIKE as the operator:
$q->orWhere('title', 'like', '%'.$book.'%');
Please change the function of details to this
function details(Request $request) {
$searchTerms = $request->book;
$books = Book::where(function($q) use($searchTerms) {
foreach ($searchTerms as $book) {
$q->orWhere('title', '%'.$book.'%');
}
})->get();
dd($books);
return view('layouts/details', compact('books'));
}

Resources