Passed data lost in Laravel paginator starting from page 2 - laravel

I am trying to list people by their appRole. Here's the controller:
public function indexByAppRole(Request $request, $appRoleId)
{
$h1 = AppRole::where('id', $appRoleId)->first()->name;
return view('admin.people.index', [
'people' => $this->people->byAppRole($appRoleId),
'appRoles' => $this->appRoles->forAll(),
'h1' => 'Role: '. $h1,
]);
}
Paginator is used in the repository:
public function byAppRole($appRoleId)
{
return Person::where('person_app_role.app_role_id', $appRoleId)
->join('person_app_role', 'person_app_role.person_id', '=', 'people.id')
->select('people.*') // fix ID confusion but why?
->paginate(20);
}
The main view lists the returned people. In the sidebar, I have the following list as side-navigation:
<ul class="list-group nav nav-pills nav-stacked">
#foreach ($appRoles as $appRole)
<li>
{{ str_plural($appRole->name) }}
</li>
#endforeach
</ul>
The navigation list works on page 1 of search results or listings, but the list is not showing up on page 2 and subsequent pages. What did I do wrong?

I solved the problem. For AppRole, I also used a paginator, so this was fixed by using all() instead of paginate() to get all appRoles.
// Before...........
public function forAll()
{
return AppRole::paginate(20);
}
And:
// After............
public function forAll()
{
return AppRole::all();
}

Related

How do I achieve a count for regions in a sub menu of categories using Laravel?

I’m trying to get a count of listings in regions under a category.
The menu for regions on the home page shows a count of all listings in their regions from every category.
On the categories page I’m trying to show a count for regions, that have listings in a selected category.
In my Listing Model
public function scopeInCategory($query, Category $category)
{
return $query->whereIn('category_id', [$category->id]);
}
public function region()
{
return $this->belongsTo(Region::class);
}
In my Region model
public function listings()
{
return $this->hasMany(Listing::class);
}
In my CategoryController
class CategoryController extends Controller
{
public function index(Category $category)
{
$regions = Region::with(['listings' => function($query) use ($category) {
$query->inCategory($category);
}])->first('region')->get();
return view('categories.index', compact('regions'));
}
}
and in my region_dropdown.blade.php
#foreach($regions as $region)
<a class="dropdown-item" href="#">{{ $region->name }}
( {{ $region->listings->count() }} )</a>
#endforeach
But this is not working the region menu still shows a count of all listings in every category on the categories page.
You can use Eloquent's withCount method to get a count of Listings under each Region by a specific Category and then access the counted value on each Region by accessing the listings_count attribute that Eloquent will initialize for you.
class CategoryController extends Controller
{
public function index(Category $category)
{
$regions = Region::withCount([
'listings' => fn($q) => $q->where('category_id', $category->id)
])->get();
return view('categories.index', compact('regions'));
}
}
And in your blade file:
#foreach($regions as $region)
<a class="dropdown-item" href="#">
{{ sprintf('%s (%d)', $region->name, $region->listings_count) }}
</a>
#endforeach
Feel free to ask for any clarification.

Stuck on many to many to many data call for an uni Assignment

I have an assessment I am not having an easy time of. I keep getting stuck on very small stuff. Im a 3d artist learning to code. So the part I am currently stuck on (small part of quite a large assignment) is I have a home page that lists restaurants like a food portal similar to like uber eats. Clicking on those restaurants is meant to load up a specific menu to the restaurant. But I can't seem to get this working. The database has 10 menu items per restaurant ID and 5 Restaurants in total. I am using sqlite3 as the database with seeder data'.
Ive had many errors but the latest is "Call to undefined relationship [menus] on model [App\Menu]."
Any help is appreciated, Ive already wasted so much time on seeder issues and now getting stuck on this part feels so trivial compared to the rest of the assignment :(
Hopefully I have provided enough information. Thanks!
Routes page:
Auth::routes();
Route::resource('/', 'HomeController');
#Route::resource('show', 'MenuController');
Route::resource('main', 'HomeController');
Route::get('show/{id}', 'MenuController#show')->name("show");
Main blade
<p>
#foreach($restaurants as $restaurant)
<a href="{{ route('show', $restaurant->id) }}">
<ul>
<li>
{{ $restaurant->name }}
</li>
</ul>
</a>
#endforeach
</p>
Show.blade
#extends('layouts.app')
#section('title')
Home Page
#endsection
#section('content')
#foreach($menus->menu as $menu)
<td>
{{ $menu->id }}
</td>
#endforeach
users.php
public function restaurant(){
return $this->hasMany(Menu::class,'App\Restaurant');
}
Restaurant.php - Model
public function user(){
return $this->belongsToMany('App\User');
}
Menu.php - Model
public function user(){
return $this->belongsToMany(User::class, 'menus_id');
}
Home Controller
public function index()
{
$restaurants = Restaurant::all();
return view('home', compact('restaurants'));
//return view('home')->with('restaurants', $restaurants);
}
Menu Controller
public function index()
{
$menus = Menu::all();
return View::make('show', compact('menus'));
}
public function show($id)
{
$menus = Menu::find($id)
->with('menus')
->where('id', $id)
->first();
return view('menu.show', compact('menus'));
}

Method Illuminate\Database\Eloquent\Collection::links does not exist

I created a model relationship between User and Message. I want to implement a list of messages for the authenticated user but I get the following error.
Method Illuminate\Database\Eloquent\Collection::links does not exist
Controller
public function index()
{
$user_id = auth()->user()->id;
$user = User::find($user_id);
return view('message.index')->with('messages', $user->message);
}
Message provider
class message extends Model
{
public function user() {
return $this->belongsTo('App\User');
}
}
User provider
public function message ()
{
return $this->hasMany('App\Message');
}
index.blade.php
#extends('layouts.app')
#section('content')
<h1>messages</h1>
#if(count($messages)>0)
#foreach ($messages as $message)
<div class="well">
<h3>{{$message->user}}</h3>
<small>Written on {{$message->created_at}} </small>
</div>
#endforeach
{{$messages->links()}}
#else
<p> no post found </p>
#endif
#endsection
Error
"Method Illuminate\Database\Eloquent\Collection::links does not exist.(View: C:\xampp\htdocs\basicwebsite\resources\views\message\index.blade.php)"
Check your view blade, that method (links()) only could be used when your data model is implementing paginate() method.
If you dont use paginate(), remove this part:
{{$messages->links() }}
If you are trying to paginate your data when it gets to the view then you need to add the paginate in your controller before passing the data to the view. Example
return $users = Users::select('id','name')->paginate(10);
with that paginate method in your controller, you can call the links method to paginate your object in view as shown below
{{$users->links()}}
hope it helps you
There are 2 ways to resolve this issue:
Either use paginate function while searching data from database:
$users = DB::table('users')->where('id',$user_id)->paginate(1);
Remove links() function from index.blade.php
{{ $messages->links() }}
Remove {{ $messages->links() }} to in your index.blade.php because {{ $messages->links() }} is supported only when you use paginate
You can do something like this in your controller file.
public function index()
{
$messages = Message::all()->paginate(5);
$user_id = auth()->user()->id;
$user = User::find($user_id);
return view('message.index')->with('messages', $messages, $user->message);
}

laravel display data on a page based on id

I have a page that shows links with name of businesses that are retrieved in database like this:
Controller:
public function viewBusiness() {
// Return our "website" object
$business = Business::all();
// Pass the contents of the "html" property to the view
return view('viewBusiness', ['business' => $business]);
}
View:
#extends('master') #section('title', 'Live Oldham') #section('content')
#section('content')
#foreach ($business as $businesses)
<a target="_blank" href="{{ url('business/' . $businesses->name) }}"> {{($businesses->name) }}
</a> #endforeach
#endsection
Route:
Route::get('business/list', 'BusinessController#viewBusiness')->name('viewBusiness');
I then have added a function where user click on a link and it is taken to a page which displays all data for that specific business, however it diplays all data but for all businesses.
Controller:
function displayBusiness() {
$business = Business::all();
$address = Address::all();
return view('displayBusiness', ['business' => $business, 'address' => $address]);
}
View:
#foreach ($business as $businesses)
<p>{{$businesses->name}}</p>
<p>{{$businesses->email}}</p>
#endforeach
#foreach ($address as $addresses)
<p>{{$addresses->firstline_address}}</p>
<p>{{$addresses->secondline_address}}</p>
<p>{{$addresses->town}}</p>
<p>{{$addresses->city}}</p>
<p>{{$addresses->postcode}}</p>
<p>{{$addresses->telephone}}</p>
#endforeach
Route:
Route::get('business/{name}', 'BusinessController#displayBusiness')->name('displayBusiness');
Now here's the question, how can this code be modified so only a business that match either bussiness->name or business->id is displayed. (I guess name is taken when user clicks on a name.
Another question is how to restrict the url so that if localhost/business/{name} is not equal to any business->name in the database returns error? at the moment it shows the page no matter what you enter.
Thanks!
I do not know if I understood the question, but that may be the beginning of a solution ...
First view :
#extends('master') #section('title', 'Live Oldham')
#section('content')
#foreach ($business as $businesses)
<a target="_blank" href="{{ url('business/' . $businesses->id) }}"> {{($businesses->name) }}
</a> #endforeach
#endsection
Second Controller :
function displayBusiness($id) {
$business = Business::find($id);
$address = Address::find($id);
return view('displayBusiness', compact('business', 'address'));
}
Second View :
<p>{{$business->name}}</p>
<p>{{$business->email}}</p>
<p>{{$address->firstline_address}}</p>
<p>{{$address->secondline_address}}</p>
<p>{{$address->town}}</p>
<p>{{$address->city}}</p>
<p>{{$address->postcode}}</p>
<p>{{$address->telephone}}</p>
Second Route :
Route::get('business/{id}', 'BusinessController#displayBusiness')->name('displayBusiness');
Route parameters are available in the controller function as parameters. Now you can build a query with this function. If your query does not return any results, you can send the user back to the business overview.
function displayBusiness($name) {
$business = Business::where('name', $name)->orWhere('id', $name)->first();
if ($business === null)
{
// No business with this name or id found.
// Redirect to businesses list page.
}
$address = Address::all();
return view('displayBusiness', ['business' => $business, 'address' => $address]);
}

Laravel - How to return last value from user input into a view

I'm building a backend for my website in Laravel. I need only few text boxes to populate a template. So far I've managed to do that, but every time I pass a value to a template I see also all previous values, not only the last one.
So for example if I'm editing slider title, I see also all previous slider titles - I want to see only last one.
My controler:
public function store()
{
$input = Input::all();
homepage::create([
'slider_title' => $input['slider_title'],
]);
return Redirect::to('/');
}
Part of view responsible for displaying slider title:
#foreach ($homepage as $home)
{{$home->slider_title}}
#endforeach
View for user input in admin:
{{ Form::open(['url' => '/admin']) }}
<div>
{{ Form::label('slider_title', 'Slider title:') }}
{{ Form::text('slider_title') }}
</div>
<div>
{{ Form::submit('Change a slider title') }}
</div>
{{ Form::close() }}
Route for admin:
Route::post('/admin', 'AdminController#store');
Route for main page:
Route::get('/', 'PageController#home');
PageController home method:
public function home()
{
$homepage = Homepage::all();
return View::make('home')->with('homepage',$homepage);
}
I tried changing PageControl with:
$homepage = Homepage::orderBy('id', 'desc')->first();
but I'm getting this error:
ErrorException: Trying to get property of non-object on my view page
public function home()
{
$homepage = Homepage::all();
return View::make('home')->with('homepage',$homepage);
}
You are seeing all slides because you are selecting all of them:
$homepage = Homepage::all();
This should give you the last one:
$homepage = Homepage::orderBy('id', 'desc')->first();
or
$homepage = Homepage::orderBy('created_at', 'desc')->first();
Remember that now you are getting only one result and you cannot use foreach anymore:
foreach ($homepage as $home)
You can refer to it directly:
$homepage->slider_title
If you still want to return an array to use foreach, this is an option:
$homepage = array( Homepage::orderBy('created_at', 'desc')->first() );

Resources