stuck at DB query, laravel - php

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

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 */

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;
}
}

Laravel Collections - Results order

The following....
Controller:
public function treatmentsList()
{
$treatments = Treatment::with('category')->where('status', 1)->orderBy('medical_name')->get();
$groups = $treatments->groupBy('category.name');
return view('pages.treatments.list', compact( 'groups'));
}
View:
<ul>
#foreach($groups as $category_name => $treatments)
<li>
<h4>{{ $category_name }}</h4>
<ul>
#foreach($treatments as $treatment)
<li>
<h5>{{ $treatment->medical_name }}</h5>
</li>
#endforeach
</ul>
</li>
#endforeach
</ul>
Gives me...
The treatments grouped in their categories and in alphabetical order but the categories are not in alphabetical order.
- Category B
Treatment A
Treatment B
Treatment C
- Category A
Treatment A
Treatment B
- Category C
Treatment A
Treatment B
Treatment C
Treatment D
How can I get the treatments and categories both listed in alphabetical order?
You can get this by adding query constraints for the eager loading query:
Treatment::with(['category' => function ($query) {
$query->orderBy('name');
}])
->where('status', 1)
->orderBy('medical_name')
->get();
Hi,
I'm not sure if this is what you mean... but it did not worked... I still get the categories not alphabetically listed.
public function treatmentsList()
{
$treatments = Treatment::with(['category' => function ($query) {
$query->orderBy('name');
}])
->where('status', 1)
->orderBy('medical_name')
->get();
$groups = $treatments->groupBy('category.name');
return view('pages.treatments.listA', compact( 'groups'));
}
You're right - my mistake. I think that answer is the join query:
public function treatmentsList()
{
$treatments = Treatment::with('category')
->select('treatment.*')
->join('category', 'category.id', '=', 'treatment.category_id')
->where('treatment.status', 1)
->orderBy('category.name')
->orderBy('treatment.medical_name')
->get();
$groups = $treatments->groupBy('category.name');
return view('pages.treatments.listA', compact( 'groups'));
}
Check the names of tables and fields from above example. This should work.

Laravel 5 - Count the number of posts that are assigned to each category in a blog

I was wondering what the cleanest way was to count the number of posts that are connected to a category in my blog.
Here is how the table relationship is set up.
What I have is a hasMany relationship from the Category to the Post models like this:
In Categories Model
public function blog_posts()
{
return $this->hasMany('App\Http\Models\Blog_Post', 'category_id');
}
And in the Blog_Post Model
public function blog_categories()
{
return $this->belongsTo('App\Http\Models\BlogCategories', 'category_id');
}
In effect all I want to do is be able to return to my view the total number of posts that each category has as shown below. Where x is the number of posts within each category.
cat1 (x)
cat2 (x)
cat3 (x)
It's not hard to count I know however as I only want a count I do not want to also retrieve the records as they are not required and I also do not want to create more queries than is necessary.
I have not completed the view as yet but probably a start would be to pass through the categories in a loop to display each and add the count at the same time?
#foreach ($categories as $category)
{!! $category->name !!} - {!! Count of posts here !!}
#endforeach
Hopefully that is clear(ish)!
Eager load the relation in your controller:
public function index()
{
$categories = Category::with('blog_posts')->get();
return view('categories.index', compact('categories'));
}
You can then use the count() method on the blog_posts relation when looping over categories in your view:
#foreach ($categories as $category)
<li>{{ $category->name }} ({{ $category->blog_posts->count() }})</li>
#endforeach
EDIT: Since Laravel 5.3, you can use withCount() to load counts of relations, i.e.
$categories = Category::withCount('blog_posts')->get();
This will make the count available via a property:
foreach ($categories as $category) {
$blog_posts_count = $category->blog_posts_count;
}
The nicest way to do it with eager loading support I know is to create a separate relation with the post count. Check this out:
public function blog_posts_count() {
return $this->hasOne('App\Http\Models\Blog_Post', 'category_id')
->selectRaw('category_id, count(*) as aggregate')
->groupBy('category_id');
}
public function getBlogPostsCountAttribute() {
if(!array_key_exists('blog_posts_count', $this->relations))
$this->load('blog_posts_count');
$related = $this->getRelation('blog_posts_count');
return $related ? (int) $related->aggregate : 0;
}
Usage is simple:
{{ $category->blog_posts_count }}

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()

Categories