Laravel 5.7 | Pagination - eloquent query (relationship table) - laravel

how can I use pagination, where my eloquent query looks:
PageController - method show:
$page = Page::where('slug', $slug)->with(['subpages'=>function($q) {
$q->where('visible', 1)->orderBy('order', 'asc')->paginate(9);
}])->first();
I would like to paginate subpages on page's View blade (Page - one to many - Subpage relationship)
Here is part of my show.blade.php view:
{{ $page->subpages->links() }}
Error:
Method Illuminate\Database\Eloquent\Collection::links does not exist.
EDIT:
FULL FUNCTION SHOW:
public function show(PageRepository $pageRepo, $slug){
$page = Page::where('slug', $slug)->with(['subpages'=>function($q) {
$q->where('visible', 1)->orderBy('order', 'asc');
}])->first();
$subpages = $page->subpages()->paginate(2);
$sidebar = Navbar::where('type','sidebar')->orderBy('order')->with(['pages'])->get();
return view('pages.page.show', [
"page" => $page,
"subpages" => $subpages,
"sidebar" => $sidebar,
]);
}
VIEW:
<div class="row display-flex">
#foreach($page->subpages as $subpage)
<div class="col-sm-4">
<div class="card mb20">
<div class="card-block">
<h4 class="card-title font400">{{ $subpage->title }}</h4>
</div>
</div>
</div>
#endforeach
</div>
{{ $subpages->links() }}

If your goal is to paginate the relation from what I see, but you're querying the parent model. That's what's wrong. You have to completely change your logic since the subquery doesn't map the relation inside the Laravel Model. It's just used as a condition to retrieve that model.
You query should look like this:
$page = Page::where('slug', $slug)->with(['subpages'=>function($q) {
$q->where('visible', 1)->orderBy('order', 'asc') // ->paginate(9); This is not necessary
}])->first();
Now that you have the parent model, you can execute a new query for the relation, and there you have to call the paginate method:
I don't think that would be a good practice to do something like this in your blade view:
{{ $page->subpages()->paginate(9)->links() }}
But it's better to implement a new variable:
// Previous code that retrieves the page
$subpages = $page->subpages()->paginate(9);
return response()->view('your.blade.view', compact('page', 'subpages');
now you can use the subpages variable, that contains the paginated results, in your view

Related

Problemes in retrieving completed courses

I'm new on Laravel 6 and build an application for students. The tables of my database look as follows:
$courses
-program_id
-title
$projects
-user_id
-course_id
-title
-completed
-comments
I have two users with different rights (Admin and Member). The Admin user can decide if a project is completed or not (checkbox). Each project belongs to a course (course_id).
I have a success.blade.php which looks as follows:
#extends('layouts/app')
#section('content')
<div class="row justify-content-center">
<div class="jumbotron col-8">
<h4 class="display-4">{{ __('Finished Projects') }}</h4>
<ol>
#foreach(Auth::user()->projects as $project)
#if($project->comments)
#if($project->completed === 1)
<li>{{ $project->title }}</li>
#endif
#endif
#endforeach
</ol>
{{ __('Back')}}
</div>
</div>
#endsection
This file retrieves completed projects, but I would like to retrieve the courses of the completed projects instead. How can I solve this?
My Controller method looks like this:
public function success()
{
$programs = Program::orderBy('name')->get();
$courses = Course::orderBy('title')->get();
$projects = Project::orderBy('title')->get();
return view('/success', [
'programs' => $programs,
'courses' => $courses,
'projects' => $projects
]);
}
you can access to desire course with this query for each project that is completed:
$course = Course::find($project['course_id']);
Using relationships
https://laravel.com/docs/7.x/eloquent-relationships
// From controller you can do
$courses = Course::whereHas('project', function($q){
$q->where('completed', true);
})->get();
// Also this way
$completedProjects = Project::where('completed', true)->get();
// Blade view
#foreach($completedProjects as $project)
#foreach($project->courses as $course)
{{ $course->title }}
#endforeach
#endforeach

Pagination in laravel with conditions

I having problem with pagination, so far I looked at the docs but I can not find in there. I also looked at other post on stack overflow but they don't have the conditions I have in this case. So how can I paginate the if statement because I get the error
Undefined property: Illuminate\Pagination\LengthAwarePaginator::$threads
because when you paginate you need to get it straight out of the model like this model::paginate() so how can you do it in this case?
the controller
public function index(Request $request)
{
if($request->has('tags')){
$tag = Tag::find($request->tags)->paginate(10);
$threads = $tag->threads;
} else {
$threads = Thread::paginate(10);
}
return view('thread.index', compact('threads'));
}
so how can you properly paginate $tag = Tag::find($request->tags)->paginate(10); this?
the blade that generates a link where the controller get the tag from if that link is clicked
<div class="col-md-3">
<h4>Tags</h4>
<ul class="list-group">
<a href="{{route('thread.index')}}" class="list-group-item">
<span class="badge">14</span>
All Threads
</a>
#foreach($tags as $tag)
<a href="{{route('thread.index',['tags' => $tag->id])}}" class="list-group-item">
<span class="badge">14</span>
{{$tag->name}}
</a>
#endforeach
</ul>
Update
var_dump($request->tags); in the controller drops string(1) "2"
You can use the whereHas() method to add relational conditions (docs).
if ($request->has('tags')){
$threads = Thread::whereHas('tags', function ($query) use ($request) {
$query->whereIn('tags.id', $request->tags);
})->paginate(10);
} else {
$threads = Thread::paginate(10);
}
In this example you need to change the third line with the whereIn method to your correct needs.

Foreach doesnt work in my View in laravel 5.6

public function getValues(Request $request){
$typ=$request->get('typ');
$stellentyp=$request->get('stellentyp');
$bereich=$request->get('bereich');
$abschluss=$request->get('abschluss');
$user = DB::table('users')->get();
$angebots = DB::table('angebots') ->orderBy('stellenname', 'asc');
if(!empty($request->get('stellentyp'))){
$angebots->where('stellentyp', $stellentyp);
}
$angebots->get();
$row = $angebots->count();
return view('user/angebots', compact('typ', 'stellentyp', 'bereich', 'abschluss', 'row', 'angebots', 'user'));
}
this is my controller
{{$row}} Angebote insgesamt
<div class="row">
#foreach ($angebots as $angebot)
<div class="col-12 col-md-6 col-lg-4 pt-4">
<div class="card offer-card">
<div class="card-image">
<img class="img-fluid" src="{{ asset('uploads/avatars/' . $user[$angebot->firma -1]->avatar) }}">
</div>
<div class="card-body">
<h4 class="text-j4y-dark praktikumstitel">{{ $angebot->stellenname }}</h4>
Jetzt mehr anzeigen ยป
</div>
</div>
</div>
#endforeach
</div>
and this is my view
but i got this error message:
Undefined property: Illuminate\Database\MySqlConnection::$firma (View: C:\wamp\sites\j4ylara\resources\views\user\angebots.blade.php)
if I put the get behind my first statement so like this
$angebots = DB::table('angebots') ->orderBy('stellenname', 'asc')->get();
but then the filter doesn't work
I don't know how I can view my results
I only know this way
{{$angebot[1]->stellenname}}
but I want all my results so I use a foreach but it doesn't work
does anyone know why?
In the following snippet
$angebots = DB::table('angebots') ->orderBy('stellenname', 'asc');
if(!empty($request->get('stellentyp'))){
$angebots->where('stellentyp', $stellentyp);
}
$angebots->get();
You're doing $angebots->get() which returns the results of your query. You need to assign the results of your query to a variable and pass that into your view. You could do something like this:
$angebots = $angebots->get();
Which would assign the result of the query to $angebots and then you could use it in your view.
Personally, I would consider renaming $angebots to $angebotsQuery or something similar and then do this:
$angebotsQuery = DB::table('angebots') ->orderBy('stellenname', 'asc');
if(! empty($request->get('stellentyp'))){
$angebotsQuery->where('stellentyp', $stellentyp);
}
$angebots = $angebotsQuery->get();
You are sending the Builder in $angebot. Try putting the results in a variable.
public function getValues(Request $request){
$typ=$request->get('typ');
$stellentyp=$request->get('stellentyp');
$bereich=$request->get('bereich');
$abschluss=$request->get('abschluss');
$user = DB::table('users')->get();
$angebots = DB::table('angebots') ->orderBy('stellenname', 'asc');
if(!empty($request->get('stellentyp'))){
$angebots->where('stellentyp', $stellentyp);
}
$angebots = $angebots->get();
$row = $angebots->count(); //this will not cause an issue since the Collection has a count method
return view('user/angebots', compact('typ', 'stellentyp', 'bereich', 'abschluss', 'row', 'angebots', 'user'));
}

Return Logged User's Posts Into laravelcollective/html Select Dropdown Menu Within a Form

I am trying to pass only the posts created by the logged in user into a laravelcollective/html select drop down menu within a form.
In my code I have two examples. Using the variable example shows how I can get the dropdown select menu to show all results from the posts table. Using the variable posts in a foreach loop shows how I can return just the posts created by the logged user, but not in a select menu.
I need to have the dropdown menu function as in the form using example but displaying results of the foreach posts loop.
Controller
public function createPost()
{
$example = Post::pluck('title', 'id')->all();
$posts = Posts::all();
return view('post.create', compact('posts', 'example'));
}
Example View
<div class="form-group">
{!! Form::label('example', 'Posts:') !!}
{!! Form::select('example', ['' => 'Select'] + $example, null) !!}
</div>
Foreach Loop Posts View
#foreach($posts as $post)
#if(Auth::user()->id == $post->user_id)
{{ $post->title }} <br>
#endif
#endforeach
try $posts = Posts::where('user_id',\Auth::id())->get()->pluck('title','');. It will return only posts of logged in user.
{{ Form::select('example', $posts) }}
You are using select box wrong.
#foreach($posts as $post)
#if(Auth::user()->id == $post->user_id)
{{ $post->title }} <br>
#endif
#endforeach
I would update your controller to only return posts by the user rather than rely on the foreach check if Auth::user()->id == $post->user_id
public function createPost()
{
$posts = Posts::where('user_id', auth()->user()->id)->get();
return view('post.create', compact('posts'));
}
As a side note, your method should probably just be create() to keep inline with the standard CRUD.
Then in your blade,
<div class="form-group">
{!! Form::label('post', 'Posts:') !!}
{!! Form::select('post', ['' => 'Select'] + $posts, null) !!}
</div>

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