Laravel get data from belongsToMany relationship - laravel

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

Related

undefined variable Posts

I am trying to complete a search filter feature for my website however i am recieving the following error:
Undefined variable: posts (View:
#foreach($posts as $distance)
<option value="{{$distance->distance}}">{{ $distance->distance}}</option>
#endforeach
Here is my search.blade.php (error occuring:
#foreach($posts as $distance)
<option value="{{$distance->distance}}">{{ $distance->distance}}</option>
#endforeach
</select>
SearchController.php
function index()
{
$posts = DB::table('posts')
->groupBy('title')
->get();
return view('posts.search')->with('posts', $posts);
}
Does anyone know why i am receiving the error even thoough my posts have been defined.
In your Controller
public function index()
{
$posts = DB::table('posts')
->groupBy('title')
->get();
return view('posts.search',compact('posts'));
}
In your model
#foreach($posts as $distance)
<option value="{{$distance->id}}">{{ $distance->distance}}</option>
#endforeach

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

404 not found in laravel

hi m trying to show a data on show.blade.php but it says 404|not found m using resource route for it. Remember m shwing the students on teacher index and from there i wants to redirect it to student/show.blade.php
StudentController:
public function show(Student $student)
{
$data = Student::findOrFail($student->id);
return view('student.show', compact('data'));
}
teacher blade file:
<td>
#foreach($row->student as $st)
<a href="{{ route('student.show', $row->id) }}">
{{ $st->student_name }}</a>
#endforeach
</td>
you are passing id into your controller not a model so the correction is here
public function show($student)
{
$data = Student::findOrFail($student);
return view('student.show', compact('data'));
}
and also correct this part on your blade
<a href="{{ route('student.show', $st->id) }}">
you get error not found because $student->id is returning null because you sending incorrect looping part therefore you got error 404
I don't know your route to students, but If you have a route like this:
Route::get('students/{id}', 'StudentController#show')->name('student.show');
What is the name of the array that you are passing with student collection from
TeacherContoller? $data?
If so, your blade file "teacher.blade.php" would be like this:
<td>
#foreach($data as $row)
<a href="{{ route('student.show', ['id' => $row->id]) }}">
{{ $row->student_name }}</a>
#endforeach
</td>
Then, you would change your method to be like this:
/**
* #var int $id
*/
public function show(int $id)
{
$data = Student::findOrFail($id);
return view('student.show', compact('data'));
}

Reach pivot table fields Laravel 5.5

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

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