Reach pivot table fields Laravel 5.5 - laravel

I created 3 tables :
categories
id
admin_id
created_at
updated_at
deleted_at
langs
id
langname_fr
langname
....
And a pivot table with fields i could fill :
category_lang
lang_id
category_id
catname
catshortname
....
In a controller i created a method index() :
public function index()
{
$categories = Category::with('langs')->get();
$categoriesCount = Sector::count();
return view('admin.pages.maps.index', compact('categories', 'categoriesCount'));
}
Now i would like to "reach" the fields in the pivot table ... for example how can i display "catname" in my view ?
Here is my model (Category model) :
public function langs() {
return $this->belongsToMany('App\Lang')
->withPivot(
'sectname',
'sectshortname',
'sectdescription',
'sectshortdescription',
'created_at',
'updated_at',
'deleted_at'
);
}
In the view :
#foreach($categories as $category)
<pre>
{{ var_dump($category->pivot->catname) }}
</pre>
#endforeach
it returns : Trying to get property of non-object

In Category model:
public function langs()
{
return $this->belongsToMany(Category::class)->withPivot('catname');
}
Now you can retrieve data like...
$categories->langs->pivot->catname
Ref: Laravel's Eloquent: Relationships
A good article: Pivot tables and many-to-many relationships

You can sipmly add ->pivot keyword like this :
#foreach($categories as $category)
#foreach($category->langs as $lang)
<pre>
{{ var_dump($lang->pivot->catname) }}
</pre>
#endforeach
#endforeach

You can just use another foreach loop to retrieve langs with pivot data,
#foreach($categories as $category)
#foreach($category->langs as $lang)
{{ $lang->pivot->sectname }}
#endforeach
#endforeach

Thank to all answers i finally found :
#foreach($categories as $category)
#foreach($category->langs as $translation)
<pre>
{{ dd($translation->pivot->sectname) }}
</pre>
#endforeach
#endforeach

Related

How to Show Subcategory Count beside each Parent Category in Laravel

in my laravel application I have categories and subcategories in the same db table. Any Category with NULL in parent column is a parent category while any category with an ID in its parent column is a subcategory.
In my view table I want to have the number of subcategories beside each parent category but I don't know how to pass the number of each subcategory along with the parent category from the control to view
public function index()
{
//select parent categories
$arr['categories'] = Category::where('parent', NULL)->orderBy('category', 'asc')->get();
return view("admin.categories")->with($arr);
}
#foreach($categories as $item)
<td>{{$count++}}</td>
<td>{{$item->category}}</td>
<td>#</td>
<td>#if($item->id != 0)
<img src="{{asset('assets/images/edit.png')}}" alt="Update" title="Update" width="20" align="left" style="margin-right:20px;">
<form action="{{ url('admin/categories' , $item->id ) }}" method="POST">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<input type="image" src="{{asset('assets/images/delete.png')}}" alt="Delete" title="Delete" width="20" onClick="return deleteItem();">
#endif</td>
#endforeach
App\Models\Category.php
public function subcategory()
{
return $this->hasMany(Category::class, 'parent_id', 'id');
}
App\Http\Controllers\CategoryController.php
public function index()
{
//select parent categories
$arr['categories'] = Category::withCount('subcategory')->where('parent', NULL)->orderBy('category', 'asc')->get();
return view("admin.categories")->with($arr);
}
resources\views\admin\categories.blade.php
#foreach($categories as $item)
...
<td>{{ $item->subcategory_count }}</td>
...
#endforeach
Issue rectified. I just added in to my Category Model
public function subCategories()
{
return $this->hasMany(static::class, 'parent');
}
and added this to my view
{{#count($item->subCategories)}}
#foreach($item->subCategories as $subCaty)
{{$subCaty->category}},
#endforeach
that did the magic
I got the help from youtube.com/watch?v=1N8KoF4H218

Use "where" and "limit" to child in #foreach

I want to display all user's profile into views and they posts. It's pretty simple:
#foreach($profiles as $profile)
{{ $profile->name }}
#foreach($profile->posts as $post)
{{$post->title}}
#endforeach
#endforeach
But I want to display only the latests posts (->orderBy('created_at', 'desc')->limit(4) ) and only accepted posts (->where('accept', 1)). How can I do that?
You already have what you need. You just need to put it all together.
#foreach($profile->posts()->where('accept', 1)->orderBy('created_at', 'desc')->limit(4)->get() as $post)
I would consider creating a query scope on your profile model. That way you can do something like $profile->latestPosts.
Or you can use the relationship to return exactly what you need.
public function latestPosts() {
return $this->posts()->where('accept', 1)->orderBy('created_at', 'desc')->limit(4)->get();
}
Then you could use it as:
#foreach($profile->latestPosts() as $post)
{{$post->title}}
#endforeach
A better solution would be to lazy load the posts you need when loading the profiles in the controller.
$profile = Profile::with(['posts' => function ($post) {
$post->where('accept', 1)->orderBy('created_at', 'desc')->limit(4);
}])->limit(10)->get();
then in the blade you can do the same as before
#foreach($profiles as $profile)
{{ $profile->name }}
#foreach($profile->posts as $post)
{{$post->title}}
#endforeach
#endforeach
if you want to use a scope for latestAccepted, you can on the Post model
class Post extends Model
{
public function scopeLatestAccepted($query)
{
return $query->where('accept', 1)->orderBy('created_at', 'desc')->limit(4)
}
}
Then lazy load it
$profile = Profile::with(['posts' => function ($post) {
$post->latestAccepted();
}])->limit(10)->get();
what you have to do is pretty simple.
create table users
create table post
create a relationships between the 2 tables
write you code in controller to join the table and query all the users post based on his/her username or password
see sample screenshot for table relationships
//Controller
Public function ViewPost(){
$data['data']=DB::table('useratable')
->where('useratable.username','=', $uname)
->where('useratable.password','<=',$pwd)
->leftjoin('posttable', 'useratable.idusertable', '=', 'posttable.userid')
->orderby('posttable.idposttable','desc')
->get();
}
//Route
Route::get('/view-post','YourController#ViewPost')
//view
#foreach($data as $r)
{{ $r->fullname}} <br>
{{ $r->email}} <br>
{{ $r->topic }} <br>
{{ $r->content }} <br>
{{ $r->datetime}} <br>
...
#endforeach
You need some codes like it on controller:
$profiles = Profile::with(['posts' => function ($query) {
$query->where('accept', 1)
->orderBy('created_at', 'desc');
}])->get();
And add this one to blade file:
#foreach($profiles as $profile)
{{ $profile->name }}
#foreach($profile->posts as $post)
{{$post->title}}
#if ($loop->iteration == 4)
#break
#endif
#endforeach
#endforeach

How to redirect one category to sub category?

This is FrontController
public function index(){
$categories = DB::table('categories')
->select('category')
->groupBy('category')
->get();
return view('front', compact('categories'));
}
This is blade layout
#foreach($categories as $category)
<h2 class="card-title">{{$category->category}}</br></h2>
#endforeach
My question is when i click any category redirect to related to subcategory...How can i do that??
In your controller, you can do the following:
// for categories
public function index() {
$categories = DB::table('categories')
->select('category')
->groupBy('category')
->get();
return view('front', compact('categories'));
}
// for sub categories
public function subCategory($category) {
$sub_categories = DB::table('categories')
->where('category', $category)
->get();
return view('another_front', compact('sub_categories'));
}
In your blade:
// for category
#foreach($categories as $category)
<h2 class="card-title">{{$category->category}}</br></h2>
#endforeach
// for sub category
#foreach($sub_categories as $subcategory)
<h2 class="card-title">{{$subcategory->sub_category}}</br></h2>
#endforeach
And the Route is:
Route::get('/subcategory/{category}', 'FrontController#subCategory');
Can you try this
This is route file "web.php"
project_url /category/{catid}
This is blade layout
#foreach($categories as $category)
<h2 class="card-title">{{$category->category}}</br></h2>
#endforeach

Laravel get data from belongsToMany relationship

in my web site i have Products and ProductCategories which they are belongsToMany relationship, with
Controller:
$products = Products::paginate(10);
View:
#foreach($products as $product)
{{$product->productCategories}}
#endforeach
i have this result:
[{"id":6,"category_name":"\u062f\u0645 \u0646\u0648\u0634 \u0647\u0627","lang":"fa",
"images":{"images":{"original":"\/uploads\/post_images\/2017\/1513065012.jpeg"},
"created_at":"2017-12-12 07:50:12",
"updated_at":"2017-12-12 07:50:12","pivot":{"products_id":44,"product_categories_id":6}}]
now how can i access to category_name in this result?
this code don't work for me and i get error:
{{$product->productCategories->category_name}}
error:
Property [category_name] does not exist on this collection instance.
or
{{$product->productCategories['category_name']}}
error:
Undefined index: category_name
You need to iterate over collection:
#foreach($products as $product)
#foreach($product->productCategories as $category)
{{ $category->category_name }}
#endforeach
#endforeach

Can't use pagination on hasMany relationship

Here's my category model:
public function products() {
return $this->hasMany('Product');
}
Then i am printing all products that each category has:
#foreach($category->products as $product)
{{ $product->title }}
#endforeach
However it prints every related product to this category. How can i use pagination in that case? I've tried to print pagination links at the bottom:
<div class="pager">
{{ $category->products()->paginate(12)->links() }}
</div>
It does print pagination links correctly, but when i change the page - content is not changing.
Before sending data to view first paginate the result like this.
$products = $category->products()->paginate(12);
now pass this value to the view and just iterate it.
#foreach($products as $product)
{{$product->title}}
#endforeach
To display links just call links method on the products in the view.
{{$products->links()}}
You want to call paginate your products first:
public function products() {
return $this->hasMany('Product');
}
public function recentProducts() {
return $this->products()->paginate(12);
}
Then in your view you loop through
#foreach($category->recentProducts() as $product)
{{ $product->title }}
#endforeach
Then your links
<div class="pager">
{{ $category->recentProducts()->links() }}
</div>
Pass paginated collection to the view:
// controller
$products = $category->products()->paginate(12);
// view
#foreach ($products as $product)
// do what you need
#endforeach
// links:
$products->links();

Resources