I am pulling a collection from my database table using the following code.
$profileVisits = DB::table('recently_visited')
->where('visitor_id',Auth::user()->id)
->orderBy('times_visited', 'desc')->get();
return view('profile.index')
->with([
'user' => $user,
'posts' => $posts,
'profileVisits' => $profileVisits,
]);
When I dd($profileVisits) it shows the collection with the correct descending results. However, when I pull the info into my view using the following code, it doesn't descend like it's supposed to. Is the orderBy query builder being undone or something with the "return view..." code?
Code in view...
#if (!$user->profileVisits->count())
#else
#foreach ($user->profileVisits as $topVisits)
<p>{{ $topVisits->getUsername() }}</p>
#endforeach
#endif
User Model:
public function profileVisits()
{
return $this->BelongsToMany('App\Models\User', 'recently_visited', 'visitor_id', 'profile_id');
}
public function addProfileVisits(User $user)
{
$this->profileVisits()->attach($user->id);
}
public function previouslyVisited(User $user)
{
return (bool) $this->profileVisits()->get()->where('id', $user->id)->count();
}
Actually, I just figured it out. On the User Model, I added the orderBy instead of using it in the Controller. See below.
User Model:
public function profileVisits()
{
return $this->BelongsToMany('App\Models\User', 'recently_visited', 'visitor_id', 'profile_id')->orderBy('times_visited', 'desc');
}
Related
I have relation like this:
DB relation
I have a code in my model that retrieves me just one parent:
public function AllParents()
{
return $this->belongsToMany($this, 'parent', 'product_id', 'parent_id')
->select('parent', 'name');
}
I get it in my controller like this:
private function product(Product $product)
{
return $product->Product()
->with('AllParents')
->get();
}
Finally I need data like this:
Product1/Product_2/Product_3
I think I need a loop, but how to do it in Eloquent?
Just change relationship. You have mentioned pivot table name wrong one.
public function AllParents()
{
return $this->belongsToMany(Product::class, 'Product_parent', 'product_id', 'parent_id') ->select('parent', 'name');
}
and then you can access
\App\Models\Product::with('AllParents')->get()
In your Product Model. You have define relationship like this.
public function allParents()
{
return $this->belongsToMany(Product::class, 'product_parents', 'product_id', 'parent_id')->select('name');
}
And, In Controller you can get all the parents with eager loading.
Product::with('allParents')->find($productId);
And, In View you can use foreach loop to iterate every parent object.
#foreach ($product->allParents as $parentProduct)
{{ $parentProduct->name }}
#endforeach
I did like this:
I modified my controller
private function product(Product $product)
{
$allParents = [];
$parent = null;
$parent->$product->Product()->with('AllParents')->first()->id;
while ($parent != null) {
array_push($allParents, Product::all->find($parent));
$parent = Product::all()->find($parent) - first();
}
}
I have two tables let's say posts and comments with Post and Comment Model.
Post.php
public function comments(){
return $this->hasMany(Comment::class);
}
Comment.php
public function post(){
return $this->belongsTo(Post::class);
}
Now I want to load Post with comments with pagination on both Post and comments.
What I tried so far,
Post::with('comments')->pagenate();
The above code only paginates on Post Model. So I tried the following code but no luck.
In Post.php
public function comments(){
return $this->belongsTo(Comment::class)->paginate(5);
}
Post::with('comments')->pagenate();
In the controller you must put the Post variable and for each post the Comments variable with it paginate, then you return the variables.
$posts = Post::orderBy('id', 'desc')->paginate(10);
foreach ($posts as $post)
$comments = $post->comments()->paginate(2);
return view('post.index', ['posts' => $posts, 'comments' => $comments]);
Now, in the blade view, you only need to put the #foreach of the comments variable in the post and add the links to page it for you.
#foreach( $comments as $comment )
<p> {{ $comment->desc }}</p>
#endforeach
{{ $comments->links() }}
i have two tables,
1) qualifs
2) teachers
one teacher can have many qualifications
i created
pivot table; qualif_teacher
with two columns (teacher_id & qualif_id)
when i am saving teacher info, teachers qualifications are saving correctly with multiple ids, my problem is i am getting error when i try to view any teachers qualification in my blade file.
error: Object of class stdClass could not be converted to string
Route: /teachers
Index Controller:
public function index()
{
$teachers= DB::table('teachers')
$qualifs = DB::table('qualifs')->find($teachers);
return view('teachers.index',compact('teachers','qualifs'));
}
Edit Controller:
public function edit($id)
{
$qualifs = DB::table('qualifs')->find($id);
$teacher = Teacher::find($id);
return response()->json([
'status' => 'success',
'teacher' => $teacher,
'qualifs'=>$qualifs,
]);
}
View:
#if(isset($teachers))
#foreach($teachers->qualifs as $qualif)
<li>{{ $qualif->qual }}</li>
#endforeach
#endif
here you pass the variable $teachers in your find function, but find always expects int number to execute his process. Thats why you are getting this error.
So try to replace this
public function index()
{
$teachers= DB::table('teachers')
$qualifs = DB::table('qualifs')->find($teachers);
return view('teachers.index',compact('teachers','qualifs'));
}
with this code
public function index()
{
$teacher= Teacher::with('qualifs')->first();
foreach($teacher->qualifs as $ qualif)
{
$qualiflist[]=$qualif->name;
}
dd($qualiflist);
return view('teachers.index',compact('teacher','qualifs'));
}
that should be solve your problem
Change this
return view('teachers.index',compact('teachers','$qualifs'));
to
return view('teachers.index',compact('teachers','qualifs'));
You added $ and it dosen't work like this.
And in your view
#if(isset($teachers))
#foreach($teachers->qualifs as $qualif)
<li>{{ $qualif->qual }}</li>
#endforeach
#endif
Try something like this on your controller
//Please ensure you import the both related models on the top of your controller
use App\Qualifs;
use App\Teacher;
public function edit($id)
{
$teacher = Teacher::find($id); //if the id edit is accepting belongs to the teacher model
return $teacher->qualifs()->get(); //this should return all qualifications for this particular teacher so far as the relationships are set
$qualifs = Qualifs::find($id); //if the id edit is accepting belongs to the Qualif model
return $qualifs->teachers()->get(); //this should return all teachers for this particular qualifications so far as the relationships are set
}
I recently asked a question about defining many to many relationships (using belongsToMany) and it was a huge help. So now in my models I have:
Users model
public function subjects()
{
return $this->belongsToMany('App\Subject', 'users_subjects', 'user_id', 'subjects_id');
}
Subjects model
public function users()
{
return $this->belongsToMany('App\User', 'users_subjects', 'subject_id', 'user_id');
}
This way I establish a relationship between users and subjects via the users_subjects table. My next step was to create a controller, SubjectsController, which ended up looking like this:
class SubjectsController extends Controller
{
// returns the view where subjects will be displayed
public function index()
{
return view('profiles.professor.prof_didactic_subjects');
}
// get users with subjects
public function getSubjects()
{
$subjects = User::with('subjects')->get();
}
// get a single user with a subject
public function getSubject($id)
{
$materia = User::where('id', '=', $id)->with('subjects')->first();
}
}
I'm not very sure about the code in the controller though.
The final step is where it gets tricky for me, even after reading the docs: I want to pass each result to the view, so I can have multiple tiles, each populated with data from subjects the user is associated with:
#foreach ($subjects as $subject)
<div class="tile is-parent">
<article class="tile is-child box">
<p class="title">{{ $subject['name'] }}</p>
<div class="content">
<p>{{ $subject['description'] }}</p>
</div>
</article>
</div>
#endforeach
I tried many different route configurations, but kept getting either the undefined variable error or trying to access non-object error.
What's the proper course of action here? I feel I'm missing something very basic. Thanks in advance for any help.
The answer
The solution provided below by #Sohel0415 worked perfectly. My index() method on the controller now looks like this:
public function index()
{
// temporary value while I figure out how to get the id of the current user
$user_id = 6;
$subjects = Subject::whereHas('users', function($q) use ($user_id){
$q->where('user_id', $user_id);
})->get();
return view('profiles.professor.prof_didactic_subjects')->with('subjects', $subjects);
}
My route looks like this:
Route::get('/professor', 'SubjectsController#index');
I was pretty lost, so this absolutely saved me, thanks again :)
You need to pass $subjects to your view. You can use compact() method for that like -
public function index()
{
$subjects = Subject::with('users')->get();
return view('profiles.professor.prof_didactic_subjects', compact('subjects'));
}
Or using with() method like -
public function index()
{
$subjects = Subject::with('users')->get();
return view('profiles.professor.prof_didactic_subjects')->with('subjects', $subjects);
}
If you want to get Subject for a particular user_id, use whereHas() -
$subjects = Subject::whereHas('users', function($q) use ($user_id){
$q->where('user_id', $user_id);
})->get();
I have a relationship this like;
public function foods() {
return $this->hasMany('App\models\food\food', 'category_id', 'id');
}
My controller file content;
$datas = food_category::where('slug', $slug)->with('foods')->paginate(12);
But incoming datas in there all datas and this is causing bad performance. I want to paginate apply relationship datas.
If you want to paginate foods, try adding a separate method for that:
Model:
class food_category
{
public function getFoodsPaginatedAttribute()
{
return $this->foods()->paginate(12);
}
}
Controller:
$datas = food_category::where('slug', $slug)->get();
View:
#foreach ($datas as $data)
#foreach ($data->foods_paginated as $food)
{{ $food->name }}
#endforeach
#endforeach
Pass paginated collection to the view:
//view
#foreach ($datas as $data)
// do what you need
#endforeach
//link
{{$datas->links()}}