How to find user by user name in laravel? - laravel

I am trying to find user by user name while building a laravel API. This is what I'm trying
api.php
Route::get('user-profile/user/{user}', 'UserProfileController#getUserProfile');
Controller
public function getUserProfile(User $user)
{
$userId = User::where('userName', $user->userName)->first()->id; // I am expecting user id here like "1"
}
This causing 404 not found error.

By default route model binding will search for id.
You should customise the column name in your route if you want Laravel to select the user using the column userName.
In you api.php:
Route::get('user-profile/user/{user:userName}', 'UserProfileController#getUserProfile');
Assuming that your userName is unique in the table, then in your controller you should use:
public function getUserProfile(User $user)
{
$userId = user->id;
...
}
This will automatically handle 404 errors for you as opposed to this answer.

by default route model binding search for id and in your case you want search by username so all you need is to remove dependency injection from your controller parameters like this
public function getUserPortfolio($user) // fix it as $user only
{
$userId = User::where('userName', $user)->first()->id; // I am expecting user id here like "1"
}

Related

how to show authenticated user data from relations

I'm trying to show the data of the authenticated user from his relation with other tables but can't get it to work, and I'm pretty new to laravel.
the user table has a relation with level table thru level_id, and the level table has a morph relation with the languages table, I'm trying to show the language of the level of the current user
here is my user model relation
public function level()
{
return $this->belongsTo(Level::class, 'level_id');
}
and my level model
public function languages()
{
return $this->morphMany(Language::class, 'langable');
}
and in the language table, I need to get back the title of 0 or 1 like
languages['0']title.
here is my controller
public function profile()
{
$user= User::with('level')->with('offers')->get();
return view('pages.user.index',compact('user'));
}
and here is how I got the auth user
{!! auth()->user()->first_name . ' ' . auth()->user()->last_name !!}
I'm trying to get this to work
{{auth()->user()->level()->languages()->title['0']}}
but it shows me this
Try {{ $user->level->languages->title['0'] }} in your index.blade file since you are passing the $user var from your controller to it. Currently you are using the user from session.
i got the answer guys it goes like this
{{Auth::user()->level->languages[0]->title}}
that'd show the level of the current user
Okay, there are a few steps you need to get done
in your controller:
public function profile()
{
$user = Auth::user(); // gets the logged in user
return view('pages.user.profile', compact('user')); // return view with $user variable
}
in your user model add:
// appends the level data to the $user model
// so every time you retrieve a user, the level data is included and accessible
// after that you can use $user->level in your view file
protected $appends = [
'level'
];
in your level model add:
// appends the languages data to the $user model
// so every time you retrieve a level, the languages data is included and accessible
// after that you can use $level->languages in your view file
protected $appends = [
'languages'
];
NOTE: In Step 3 you are retrieving multiple languages for a level. Is that correct ?
usage in view
$user->level->languages[specificLanguage]->title // if level has multiple languages
$user->level->language->title // if level has one language

How can fill the user id field with auth user on creation of resource?

I'm sure there must be a very simple way to do this - I would like to fill the user_id field on my resource with the authenticated user's id whenever a new instance of the resource is created.
In the store() method of my Resource model I have:
public function store(Request $request)
{
$input = $request->all();
$resource = Resource::create($input);
$resource->user_id = Auth::user()->id;
return $resource;
return 'Resource added.';
}
This works through a post API route, however whenever I add a new resource instance through Nova dashboard, it does not add the Auth user id. I'm guessing this because Nova doesn't use that Resource controller that I have set out?
I would appreciate suggestions!
Working on the assumption that you have relationship method User::resources() the following should work:
return $request->user()->resources()->create($request->all());
The way you have it doesn't work because you didn't save the resource after associating user with it.
I haven't used Nova yet, but since its also laravel and most likely Eloquent ORM I can tell the following.
In these two lines you've set the user_id but you haven't persisted the change:
$resource->user_id = Auth::user()->id;
return $resource;
You should add this line to save the changes you've done:
$resource->save();
As an alternative you could add the value already into your $input array:
$input = $request->all();
$input["user_id"] = Auth::user()->id;
$resource = Resource::create($input);
I just created an ResourceObserver. Saved the Auth()->user->id with the created method.
Registered the ResourceObserver to AppServiceProvider and NovaServiceProvider.
https://laravel.com/docs/5.7/eloquent#observers
https://nova.laravel.com/docs/1.0/resources/#resource-events
In the model class, add function like this:
public function save(array $options = array())
{
$this->user_id = auth()->id();
parent::save($options);
}
Just be carefull if you tend to use save in any other scenario so you don't overwrite existing user_id.

Laravel am I doing multiple queries by calling the Auth::user() multiple times in my controller

In my controller I get the logged in user id and username like this:
$userId = Auth::user()->id;
$username = Auth::user()->user_name;
But will the above code produce two queries?
I dont understand how Auth::user() works behind the scene
If your code generates 2 query save user in another variable.
Like this:
$user = Auth:user();
$userId = $user->id;
$username = $user->user_name;
Laravel does not store all user in session, it stores only user id. And when call user() function laravel will get user from database with saved user id.
Auth::user() return an object with your user data from the users table.
So, if you want just one query, use :
$user = Auth::user();
echo $user->user_name;
Have a look on official doc, at Validation section.
Be sure that your user is logged before call Auth method :
if (Auth::check()) {
// User logged
}
If you want reduce database query, fetch Authenticated user like this:
$user = Auth::user():
$id = $user->id;
$name = $user->name;
dd($user);
In laravel Auth::user() has all data of current authenticated user.

Getting ID from url and using it in CRUD controller laravel

I need to add orders to existing customers. From my customers.show view I use the following to visit the order form.
href="{{action('OrderController#create', $customer['id'])}}
The link of the page looks like:
/orders/create?2f10f8a0-30b9-11e8-8711-dd477b141226
I've been using the following route::get to no avail to be able to use this ID in my resource controller for Orders
Route::get('orders/create/{id}', 'OrderController#create');
Basically need to be able to to something along the lines of below to be able to show customer details while displaying the create order form as well but getting stuck on best way to pass the id through for the current customer
public function create(){
$customer = Customer::find($id)
return view('orders.create', compact('customer'));
}
With Laravel, you just need to add the parameters you specified in the route as function parameters, like below:
public function create($id){
$customer = Customer::find($id)
return view('orders.create', compact('customer'));
}
You are not passing the $id argument in the create function.
Change it to:
public function create( $id ){
$customer = Customer::find($id)
return view('orders.create', compact('customer'));
}

Relationship with user condition

I have a follow system that works like Twitter's follow (you follow other people and get updates from them).
I have this relationship set in my User.php model:
public function follows()
{
return $this->hasMany('App\Follow');
}
This obviously gets all records of users who follow this person.
However, when displaying the person's profile page, I want to get a relationship that checks if a follow record exists given the user ID.
Something like:
public function userFollow()
{
return $this->hasOne('App\Follow')->where('user_id', Auth::user()->id);
}
So now my profile page query looks like this:
$user = User::where('username', $username)
->with('userFollow')
->first();
This works as long as the user is logged in. If the user isn't logged in, the page gives me this error:
ErrorException in User.php line 28: Trying to get property of
non-object
How do I fix this? What is the proper way of using conditions in relationships?
This is because if user is logged out then Auth::user() is null, because user session has ended. Auth::user() is no more object, so you can't get the id from a null object.
Here you can do something like that
public function userFollow()
{
$userId = Auth::user() ? Auth::user()->id : $this->id;
return $this->hasOne('App\Follow')->where('user_id', $userId);
}
then it will not look for authenticated user, it will just get the particular user table's id.
The proper way of using conditions in relationships is using Constraining eager loads
public function userFollow()
{
return $this->hasOne('App\Follow');
}
And,
if(Auth::check())
{
$user = User::where('username', $username)
->with(['userFollow'=>function($query)
{
$query->where('user_id', Auth::user()->id);
}]);
->first();
}

Resources