Laravel Query Builder create looping data from category - php

I am quite new in Laravel. I've googled with this keyword but no luck.
I use Laravel 8. Currently I need to view data from each category, so it will be like this on blade:
cat A
product A1 <img src=(get from thumbnail)>
product A2 <img src=(get from thumbnail)>
cat B
product B1 <img src=(get from thumbnail)>
product B2 <img src=(get from thumbnail)>
etc...
Currently my controller is:
$categories = DB::table('tbl_categories')
->orderBy('name')
->get();
foreach($categories as $key) {
$data = DB::table('tbl_product')
->where('status','Enable')
->where('category_id',$key->id)
->get();
}
$thumbnail = DB::table('tbl_thumbnails')
->where('product_id',$data[0]->id)
->get();
return view('/products', ['categories' => $categories, 'data' => $data, 'thumbnail' => $thumbnail]);
in my blade:
#foreach($categories as $discover_category)
<div>
#foreach($data as $discover)
#foreach($thumbnail as $a)
<!-- product name and thumbnail in here-->
#endif
#endif
</div>
#endif
But the result is now show only last category_id. please help. GBU.

you need to use first() to get single value like this
foreach($categories as $category) {
$products = DB::table('tbl_product')
->where('status','Enable')
->where('category_id',$category->id)
->get();
foreach ($products as $product) {
$thumbnail = DB::table('tbl_thumbnails')
->where('product_id',$product->id)
->first();
// assign value to $product
$product->thumbnail = $thumbnail;
}
// assign value to $category
$category->products = $products;
}
then in view you can use like
#foreach($categories as $category)
<div>
#foreach($category->products as $product)
<div>
<p>{{$product->name}}</p>
<p>{{$product->thumbnail->id}}</p>
</div>
<!-- product name and thumbnail in here-->
#endif
</div>
#endif

You can use Eloquent ORM, Just simply use this kind of code on your category model like:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
/**
* Get the products for the category.
*/
public function products()
{
return $this->hasMany(Product::class);
}
}
On controller like
$categories = Category::all();
return view('products', ['categories' => $categories]);
On Blade like
#foreach($categories as $category)
<div>
<div>{{ $category->name }}</div>
#foreach($category->products as $products) // here this products object called form model
#foreach($products as $product)
<!-- product name and thumbnail in here-->
#endforreach
#endforreach
</div>
#endforeach
Note
Note: You must perfectly make the relationship between the products table and categories table. Products table must have a column named category_id

Related

Laravel filter products by category name

I use Bagisto E-Commerce platform (build laravel + vue) and I have created package where I want list categories and filter products by category name.
I don't know how exactly filter products by one view and in bagisto they list products by category page e.g. example.com/category-name
I try to use this example, but can't get it working, because I don't know where I get class "Products" and function AllProducts.
Can someone guide me in the right direction of how I could get this to work correctly?
This is what I'm trying to do: https://codepen.io/mrsingleton/pen/aYVBvV
My code in products view:
$categories = [];
foreach (app('Webkul\Category\Repositories\CategoryRepository')->getVisibleCategoryTree(core()->getCurrentChannel()->root_category_id) as $category) {
array_push($categories, $category);
}
?>
#if (count($categories))
<div class="list-container" style="text-align:center;margin-top: 50px;">
<ul class="list-group">
#foreach ($categories as $key => $category)
<li> {{ $category->name }} </li>
#endforeach
</ul>
</div>
#endif
In Bagisto, Laravel translatable has been used. Thats why you need to use the different approaach to achieve this. As directly by name, you won't be able to achive because the rest columns are on different tables i.e. category_translations.
If you check the Categories model in namespace i.e. Webkul\Category\Models\Category, it is already linked to the Product model. So you can directly chain it to fetch all associated products.
/* fetch category by name */
$categoryName = 'Category 1';
$category = Category::whereHas(
'translations',
function ($query) use ($categoryName) {
$query->where('name', $categoryName);
}
)->first();
$relatedProducts = $category->products;
/* rest is your operations */

stuck at DB query, laravel

I need your help...
Can't figure out where the problem is.
I am trying to show all products of a subcategory.Sometimes it shows the first or the last record. Then it repeats many times the same record( as the cycle is).
category: id, name, visible
products:id, name,
category_products:id, id_product, id_category
Route::get('navigation/{id}',function($id){
$prods= \App\Products_to_Categories::where('id_category',$id)->get();
$products=array();
foreach ($prods as $prod)
{
$products[] = \App\Products::find($prod->id_product)->
where('visible','yes')
-> where('delete','no')->first();
}
return view('subcategories.order_products',
['products'=>$products ]);}
View blade
<div class="col-md-6 col-md-offset-1">
<ul id="sortable">
#foreach($products as $product)
<li class="ui-state-default" id="{{ $product->id}}"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span> {{$product->name}}</li>
#endforeach
</ul>
</div>
It looks like products and categories are related through the join table category_products, so you can setup a belongsToMany() relationship and query from Category to Product without looping over the join table.
https://laravel.com/docs/5.7/eloquent-relationships#many-to-many
Category model:
public function products()
{
return $this->belongsToMany(\App\Products::class, 'category_products', 'id_category', 'id_product');
}
Products model:
public function categories()
{
return $this->belongsToMany(\App\Category::class, 'category_products', 'id_product', 'id_category');
}
Controller code:
$category = Category::find($id);
$products = $category->products()
->where('visible', 'yes')
->where('delete', 'no')
// ->inRandomOrder() // un-comment this if you want results in random order
->get();
Try this in Laravel >= 5.2: :
$prods= \App\Products_to_Categories::where('id_category',$id)->get();
$products=array();
$whereIn = array();
foreach ($prods as $prod)
{
$whereIn[] = $prod->id_product;
}
$products[] = \App\Products::find($prod->id_product)
->where('visible','yes')
-> where('delete','no')
->whereIn('id', $whereIn)
->orderByRaw('RAND()')
->get();
This will give you the list of products of a specific category in random order.
Laravel 4.2.7 - 5.1:
User::orderByRaw("RAND()")->get();
Laravel 4.0 - 4.2.6:
User::orderBy(DB::raw('RAND()'))->get();
Laravel 3:
User::order_by(DB::raw('RAND()'))->get();
source :
Laravel - Eloquent or Fluent random row

Get the id from one to many modal - Laravel

I need to get the list of product categories from the table.
2 tables in total. tblProduct & tblProductCatLink
1 product can have many product category link.
tblProductCatLink consists of product_id, category_id
Now from my controller & view, i want to get the list of categories belong to one product.
Product.php
public function productcategorylink(){
return $this->HasMany('App\ProductCategoryLink', 'product_id', 'id');
}
ProductCategoryLink.php
public function projects(){
return $this->hasMany('App\Project', 'id', 'product_id');
}
Controller
foreach ($projects as $project) {
foreach ($project->productcategorylink as $value) {
echo $value->category_id;
}
}
The above code is returning first row of category for the product only. I had 3 rows of records for product 297 in my DB.
I need to access the product category link from the view while I looping the product data
In a controller:
$products = Product::with('productcategorylink')->get();
In view:
#foreach ($products as $product)
#foreach ($product->productcategorylink as $link)
{{ $link->category_id }}
#endforeach
#endforeach
You need to call productcategorylink and projects. So it would be
$projects = projects();
foreach ($projects as $project) {
$productCategoryLink = $project->productcategorylink();
foreach ($productCategoryLink as $value) {
echo $value->category_id;
}
}

How to use Laravel Pagination with models relationsips?

I have categories and items tables. Each item belongs to only one category and each category has many items. So, in Category model I defined this relationship:
public function items()
{ return $this->hasMany('Item', 'catid'); }
and I retrieve data for a category this way:
$category = Category::find($id);
return View::make('admin.categories.catdetails')->with('category', $category);
and in my view I can loop through data:
#foreach ($category->items as $item)
<tr>
<td> {{ $item->name }} </td>
<td> {{number_format($item->price, 2, '.', '')}} </td>
</tr>
#endforeach
but this results in all items in on page. How to make use of laravel pagination in case that I have so many items for one page??
How can I use
::paginate() // in controller or model
->links() // in view
as, so far, it throws many errors and I can't figure it out.
Thanks in advance.
You can call paginate() on the relationship object, which you access by ->items() (not ->items)
$items = $category->items()->paginate(10);
return View::make('admin.categories.catdetails')
->with('category', $category)
->with('items', $items);
Then in your view:
#foreach ($items as $item)
And:
$items->links()
You could use an attribute accessor to achieve what you want. In your model:
public function getPaginatedItemsAttribute(){
return $this->items()->paginate(10);
}
And then you use it like this:
#foreach ($category->paginatedItems as $item)
And:
$category->paginatedItems->links()

one to many relationship help in laravel 4

I am trying to create a relationship between Category and Product but somehow I couldn't use the category to connect into the product table and prints out the product names and instead I get the category's name
in my database
Table Name: products
Columns: id, name, price, category_id, description
Table Name: categories
Columns: id, name, description
in products table
id: 1
name: product1
price: 10
category_id: 1
description: p1
---------------
id: 2
name: product2
price: 10
category_id: 1
description: p2
in categories table
id: 1
name: category1
description: c1
---------------
id: 2
name: category2
description: c2
Product.php inside models folder
class Product extends Eloquent
{
protected $product = 'products';
public function category()
{
return $this->belongsTo('Category');
}
}
Category.php inside models folder
class Category extends Eloquent
{
protected $category = 'categories';
public function product()
{
return $this->hasMany('Product', 'category_id');
}
}
ProfileController.php in controller folder
class ProfileController extends BaseController
{
public function user($username)
{
$user = User::where('username', '=', $username);
if ($user->count())
{
$user = $user->first();
$title = 'User Profile';
$category = Category::find(1);
$products = Category::find(1)->name;
return View::make('profile.user', compact('user', 'title', 'category', 'products'));
}
return 'User Not Found. Please Create an Account';
}
}
user.blade.php inside profile folder which is inside view folder
#extends('layouts.master')
#section('content')
{{ Auth::user()->username }}
<br>
{{ Auth::user()->email }}
<br>
<h1>{{ 'Category name: '. $category->name }}</h1>
<br>
<h3>{{ 'Category Description: ', $category->description }}</h3>
<br>
{{ $products }}
#stop
at first where the {{$products}} I used a foreach loop
#foreach($products as $product)
{{$product}}
#endforeach
but then I got this error
ErrorException
Invalid argument supplied for foreach() (View: J:\wamp\www\test\app\views\profile\user.blade.php)
so I tried var_dump($products) and realized $products gives out category1 which is the name of the category but what I want is printing the name of all the products which has category_id 1
Can someone give me a hand with this? Did I mess something up with the relationship or I did something stupid with the codes?
In your controller:
$category = Category::find(1);
$products = $category->product;
Then in your template you can use:
#foreach ($products as $product)
{{ $product->name }}
#endforeach
Better yet you could use eager loading and forget about assigning products manually:
Controller:
$category = Category::with('product')->where('id', 1)->first();
Template:
#foreach ($category->product as $product)
{{ $product->name }}
#endforeach
PS: Read more on eager loading here: http://laravel.com/docs/eloquent#eager-loading
in order to prevent the dreaded N + 1 query problem!

Categories