Laravel show() parameter are null - laravel

I am using Laravel version 5.6.26. My show() parameter get null value. Why? and how to solve it? Thank you
web.php
Route::get('/peoples', 'UsersController#index')->name('peoples');
Route::get('/peoples/{id?}', 'UsersController#show');
UserController.php
public function show(User $user)
{
$user = User::where('id', $user->id)->first();
//$user = User::find($user->id)->first();
return dd($user);
//return view('profile',['user' => $user]);
}
user.blade.php when I click <a href="/peoples/{{$user->id}}" > , it show null
<h4><a href="/peoples/{{$user->id}}" > {{$user->name}}</a></h4>
result
https://imgur.com/QlaiFse
But if i do like this,I can get the value
public function show(User $user)
{
$user = User::where('id',1)->first();
//$user = User::find($user->id)->first();
return dd($user);
//return view('profile',['user' => $user]);
}

The way you defined your show method i.e. show(User $user) is called route model binding if your variable name ($user) is similar to your route declaration. But your route declaration is /peoples/{id?} so the User instance is not created in your controller. So just rename the route declaration as /peoples/{user?}.
The use case of route model binding is you don't want to query/load the model related to a route parameter. So if you define the route the way I've mentioned you won't need the $user = User::where('id', $user->id)->first(); query. Because Laravel will automatically instantiate that $user with the User model of id passed in the route.
If you want to query/load the User model manually then keep your existing route declaration as it is. And change your controller method declaration as show($id = null)

You are injecting the User model in your controller, but not accessing the route path. If you want to access the {id} which set in the route, you have to access that in your controller too.
So your UserController will be something like
public function show(User $user, $id)
{
$user = User::where('id', $id)->first();
dd($user);
}

When you type hinted in your controller's method show() with User, Laravel will automatically inject that using Service Container.
Your UserController.php's code should be:
public function show(User $user) {
// no need to fetch user again. Laravel had already done that for you.
dd($user);
return view('profile', compact('user'));
}

Related

how to send id in route and controller in laravel localization

In my Laravel project with localization I made middleware, route group and all parameters, language switch work correct but when I click to send id by
I get the error:
Missing required parameters for [Route: products] [URI:
{lang}/products/{id}]
My Routes:
Route::group(['prefix' => '{lang}'], function () {
Route::get('/', 'AppController#index')->name('home');
Route::get('/categories', 'AppController#categories')->name('categories');
Route::get('products/{id}', 'AppController#products')->name('products');
Auth::routes();
});
My Middleware:
public function handle($request, Closure $next)
{
\App::setLocale($request->lang);
return $next($request);
}
My AppController:
public function products($id)
{
$products = Category::with('products')->where('id', $id)->get();
return view('products', compact('products'));
}
this is the URL:
http://127.0.0.1:8000/fa/products/1
if I change the above URL manually it works and shows the page:
http://127.0.0.1:8000/1/products/1
But if I click on:
I receive the error.
Since you added a route prefix the first parameter of the products method in your controller will be lang and the second one id.
This should fix the controller:
public function products($lang, $id)
{
$products = Category::with('products')->where('id', $id)->get();
return view('products', compact('products', 'lang'));
}
You need to use a key-value array in route('products', ['lang'=>app()->getLocale(), 'id'=>$category->id]) or whatever your route parameters are named in the original route.
Ref. Laravel Named Routes
PS. as Remul notes, since you have a lang param (as route prefix) the first param in your controller will be $lang then $id
public function products($lang, $id)
{
$products = Category::with('products')->where('id', $id)->get();
return view('products', compact('products'));
}

Reuse user resource route for current user

I've created a resource route for users.
Route::resource('users', 'UsersController');
My controller handles the path /user/1/edit with in my users controller like so:
public function edit(User $user)
{
$this->authorize('update', $user);
...
The template for this page is: resources/views/users/edit.blade.php.
How would I define a new route, /user/edit, which dynamically passes the current user and reuses the edit(User $user) method while also reusing the same view template?
Your edit() method will need to change to conditionally accept the User model. You then need to check if $user was passed, else assume current user is required:
public function edit(User $user = null)
{
$user = $user ?: auth()->user();
$this->authorize('update', $user);
...
And create the new route:
Route::get('user/edit', 'UsersController#edit')
Try this:
Route::get('users/{user}/edit', 'UserController#edit')->name(edit-user);
Then, pass in the user id in route like this:
route('edit-user', ['user'=>$user->id]);
I hope this helps you.

modify getRouteKeyName in Laravel 5.7

I defined slug for single DB in a column of structure DB. When I will call the slug in route, Could I get slug from another model (e.g. structure here) in route?
The route is:
localhost:8000/api/singles/firstTest
I defined getRouteKeyName function in Single model:
public function structure()
{
return $this->belongsTo(Structure::class);
}
public function getRouteKeyName()
{
return $this->structure()->select('slug')->first();
}
In your controller you will get the firstTest as route param if you have specified route as :
Route::get('api/singles/{slug}', 'SomeController#someAction');
Then controller :
public function someAction(Request $request, $slug)
{
// Perform validations and policy authorization if required
$id = Single::whereHas('structure', function ($query) use($slug) {
$query->where('slug', '=', $slug);
})->first();
if(!$id){
abort(404);
}
// Process the data using $id obtained above
}

Laravel 5.4 Sessions and Auth::user() not available in controller's constructor

I would like to use a User class throught the application. So, I would like to create CustomUser and then inject it into controllers that need it (it would be most of them).
Now, I create an empty instance in serviceprovider. Next, I want to fill it with data that are already saved in Auth::user(). After long time I have not found where to do it.
Auth::user() is empty in middlewares, but is filled with the user data in controllers. I am missing the step where Laravel queries the database and fills Auth:user() with data. I want to avoid making the same query again.
Thanks for any help!
You can use base controller with __get() method. For example:
class Controller
{
public function __get(string $name)
{
if($name === 'user'){
return Auth::user();
}
return null;
}
}
And in the child controllers can call $this->user
Since Laravel 5.3, you do not have access to sessions in controller constructors. This is because the middleware has not been run yet. I know it's difficult to locate, but in the migration documentation from 5.2 > 5.3 (you're probably on 5.4), it shows that the proper way to resolve data from sessions (which auth() is just a wrapper around a session() call to get the user), is to use the following method:
class MyController extends Controller {
protected $user;
public function __construct() {
$this->middleware(function ($request, $next) {
$this->user= auth()->user();
return $next($request);
});
}
}
Then $this->user will reference the auth user to any methods inside of this controller.
Hopefully his helps.
In Laravel 5.6 i used this
$this->middleware(function ($request, $next) {
$id = Auth::user()->id;
$res = $this->validateAnyFunction($id);
if(!$res){
//to redirect to any other route
return $next(redirect()->route("any")->with("failed","Invalid")->send());
}
//this is used to proccess futher funcitons of controller
return $next($request);
});

Error when I try to edit user

I am using Laravel 5.4.18. I am getting this error when I try to edit user
Missing argument 2 for App\Http\Controllers\UsersController::edit()
Here is what I did
https://paste.laravel.io/Pyw5M#18
Change this:
public function edit(User $user, $id)
{
$user = $user->find($id);
return view('admin/users/edit', compact('user'));
}
To this:
public function edit(User $user)
{
return view('admin/users/edit', compact('user'));
}
When you define (User $user) laravel auto-injects the user model, so no need to find the model again based on the id.
In this case i expect your route to look like this:
Route::get('users/{user}/edit', UserController#edit)
Or you can use resource controllers so this is handled for you:
https://laravel.com/docs/5.4/controllers#resource-controllers

Resources