Laravel - Get users name from ID - laravel

I have a Laravel 5.6 app that is logging various information into a database table, I am then displaying this data in a HTML view. I am calling this view like this...
$logs = Log::all();
return view('logreport.index')->with('logs', $logs);
The table only contains the user ID, is there a way to get the users first name and last name for the users table? Or do I need to set a relationship up?

if the log table contain the user_id and you want to get user name you can get the user name through relation as the following:
in log model add the following method:
public function user(){
return $this->belongsTo('App\User','user_id','id');
}
and then you can access the user information in view file such as firstname as the following
#foreach($logs as $log)
<h1>{{$log->user->first_name .' '.$log->user->last_name }}</h1>
#endforeach

You don't need to set a relationship. Just use eloquent.
$users = User::whereIn('id', array(...))->get();
Or with query builder
$users = DB::table('users')->whereIn('id', array(...))->get();
Replace the dots by the values of your IDs

You can use Eloquent relationship as answered by Ali or you can use "Joins" with your result as:
$logs = Log::join('users', 'users.id', '=', 'logs.user_id')->get();
return view('logreport.index')->with('logs', $logs);
and then access the result as:
<h1>{{ $log->first_name .' '. $log->last_name }}</h1>

Related

I have a laravel project with 2 tables (users and roles). In a roles view, I am trying to display a count of users who are using that specific role

My tables areas follows
roles table (id, roleName, roleDesc)
users table (id, name, role, email)
When adding a new user, I insert a role eg "Admin" into the role column of the user.
My problem is that I want to show the number of users who have that role in a view data table that displays list of roles. Eg would simply be an integer of number of members who share that role, eg 5.
In my roleController, I am fetching records using
$roles = Role::all();
$users = User::all();
I have managed to display a count of users with role "Admin", but this ofcourse just duplicated all down the datatable with eg "1"
$RoleCount = User::where('role', '=', 'Admin')->count();
So, I think I need to use a join or something to replace the 'Admin' above, with current roleName.
I hope that makes sense and I hope someone can help me find a solution. I know this is pretty elementary, but trying to rap my head around joins and having a bit of trouble.
Thanks in advance.
First it will be great to use Relationships (Laravel docs)
With relationships it will be super easy.
Change Users table, so you have there NO the name of role, but ID of role = columns id, name, role_id, email
In Role model add relationship to User, and in User model add relationship to Role:
Model User.php - add method
public function role(){
return $this->belongsTo('App\Role'); //use your correct namespace
}
Model Role.php - add method
public function users(){
return $this->hasMany('App\User'); //use your correct namespace
}
And then just select all roles with count of users:
$roles = Role::withCount('users')->get();
In your view:
#foreach($roles as $role)
{{ $role->roleName }} - {{ $role->users_count }}<br>
#endforeach

I am trying to return users and items datas from invoice

this is my function in Invoice Controller
public function edit(invoice $invoice, $id)
{
$invoice = Invoice::with('users', 'items.products')->findOrFail($id);
return view(compact('invoice'));
}
in my View I did
{{ $invoice->user_id->email }}
The relationship you are loading is named users so that is the name of the dynamic property for that relationship. user_id is the User's id, not the relationship.
{{ $invoice->users->email }}
This is also assuming there is always a User for the invoice.
Laravel 6.x Docs - Eloquent - Relationships - Relationship Methods vs Dynamic Properties
Side Note:
The naming could use some work since there should only be one user for an invoice I would assume, so singular. Use plural when something can have many, singular when it has one or none. The relationship should be named user.
You are using the wrong property, $invoice->user_id is probably is the raw integer value coming from the database. You need to call the relation like so:
{{ $invoice->user->email }}
$invoice->user will return the user object that is related to the $invoice->user_id id.
you forgot view name to return
public function edit(invoice $invoice, $id)
{
$invoice = Invoice::with('users', 'items.products')->findOrFail($id);
return view('invoice.edit',compact('invoice'));
}
and access with relationship name
{{ $invoice->users->email }}

Empty field in view while it has been retrieved with dd Function

I have joined two tables in Clint table controller and Appointment table as below image and dd function showing the data already.
Here is my controller:
and here is result of dd():
but in the view page it's an empty field:
and here is available I am using in the view:
I have seen your controller image and in join statement mistake.
When you join your appointment table to the clients table then you should use foreign keys.
public function show(Client $client) {
abort_if(Gate::denies('client_show'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$client = DB::table('clients') ->join('appoinments', 'clients.id', '=', 'appoinments.clint_id') ->select('clients.*', 'appoinments.start_time', 'appoinments.finish_time') ->get();
return view('admin.clients.show', compact('client'));
}
I assume in the appointment table you have clint_id.
The variable $client that you are passing to your view is from your Route Model Binding. $clients is the result of your query with the join to appointments which provides the fields start_time and finish_time. You are showing us the output of a dd on $clients which includes those fields, but passing $client to your view which most likely does not have such fields.
You could adjust what you are passing to your view to fix this:
return view('admin.clients.show', [
'client' => $clients,
]);
I am not sure what your purpose is with this method though as the route parameter doesn't end up being used. You probably want to be using that route parameter to filter your query. Though this could be a good place to try using relationships instead of directly joining with query builder.
Also, please do not put up pictures of code. Please edit your question and include the code into the question if you can. Thanks.
Laravel 6.x - Docs - Routing - Route Model Binding

Eloquent hasManyThrough also get middle table information

I have same table structure as mentioned in laravel document for HasManyThrough relationship hasManyThrough
countries
id - integer
name - string
users
id - integer
country_id - integer
name - string
posts
id - integer
user_id - integer
title - string
and define a relationship like same as in doc.
public function posts()
{
return $this->hasManyThrough(
'App\Post', 'App\User',
'country_id', 'user_id', 'id'
);
}
Now when I List posts of specific country. I need the information of user of the post too. I mean information from pivot table(users)
$posts = Country::find(2)->posts();
The above returns post data only..
What you need is to eager load the users alongside the posts, can be achieved via the with() method on the Builder:
$posts = Country::find(2)->posts()->with('user')->get();
If you're loading huge amounts of data and don't want the whole User instance loaded, you can even specify which fields to only be retrieved from the users table:
$posts = Country::find(2)->posts()->with('user:id,name')->get();
Then you can simply use $post->user->name or whatever you need when iterating your collection.
Refer to the documentation for more information.
Try this one:
$posts = Country::find(2)->posts()->with('user')->get();

get posts by self and posts by all follows with attached user using with() or joins and order by post created_at

I have a follow system setup from this tutorial.
Creating the Twitter following model in Laravel 4
It works for getting follows and followers and for saving them. But I want to list all of my posts and all posts of the people I follow, along with the related user object for each one and order them all by the posts created_at column.
Rather than try to pick some code to show what I have tried, lets just say I have spent two days trying every combination of join(), leftJoin(), nested joins, where(), orWhere(), nested wheres, with(), joins and wheres nested in with() that I can think of and I just can't figure it out.
For the follows I have a pivot table with user_id and follow_id. Here are the relationships in my User model.
/**
* User following relationship
*/
public function follows()
{
return $this->belongsToMany('User', 'user_follows', 'user_id', 'follow_id')
->withTimestamps();
}
/**
* User followers relationship
*/
public function followers()
{
return $this->belongsToMany('User', 'user_follows', 'follow_id', 'user_id');
}
Twit.php model. (Actually my posts are called twits but same concept)
class Twit extends Eloquent {
protected $fillable = ['twit', 'user_id'];
public function user()
{
return $this->belongsTo('User');
}
}
User.php model
class Twit extends Eloquent {
protected $fillable = ['twit', 'user_id'];
public function user()
{
return $this->belongsTo('User');
}
}
I've tried talking myself through this but none of the eloquent functions seem to do what I think they should do. To be clear, here is verbally what I need to happen.
Get each twit with its user and order by twits.created_at
only where user.id = Auth::user()->id
or where user.id is in Auth::user()->follows
Help writing this out as a raw query would work too.
Thanks for any help.
UPDATE: Deleted my own answer to save others from getting confused by it since it was way off and wasn't working 100%.
The selected answer works perfectly. Here is the selected answer by #philipbrown with added eager loading for the user and ordered by the twit created_at date
$twits = Twit::whereIn('user_id', function($query)
{
$query->select('follow_id')
->from('user_follows')
->where('user_id', Auth::user()->id);
})->orWhere('user_id', Auth::user()->id)
->with('user')
->orderBy('created_at', 'DESC')
->get();
And in the view
#foreach($twits as $twit)
<li>
<div class="twit-gravitar">
<img src="{{ getGravitar($twit->user->gravitar) }}">
</div>
<div class="twit">
<div class="twit-handle">
{{link_to('/twits/'.$twit->user->username, '#'.$twit->user->username) }}
</div>
<div class="twit-text">{{ $twit->twit }}</div>
</div>
</li>
<hr class="twit-separator">
#endforeach
I'll walk through step-by-step how I would solve this problem. I find it easier to get my head around the raw query before I convert that into ORM methods, so I'll write this out as I would work through it, rather than just give you the answer.
Writing the raw query
So first I would simply get all twits (I'm guessing it's twits?):
SELECT * from twits
Next I would refine this by only selecting the from the current user (using user_id 1 as an example):
SELECT * FROM twits WHERE user_id = 1
Next we can use an SQL subselect to find all the users that the current user follows:
SELECT * FROM twits WHERE user_id IN (SELECT follow_id FROM user_follows WHERE user_id = 1) OR user_id = 1
Now if you run that on your database and change the user_id you should get a stream of twits that you were expecting.
Converting to Eloquent
Now that we have the raw query sorted, we can convert it to use Eloquent so you are returned an Eloquent Collection.
Again, first start by simply getting all twits:
$twits = Twit::all();
Next we need to use the whereIn method:
$twits = Twit::whereIn('user_id', array(2, 3, 4))->get();
But instead of passing an array of user ids, we need to pass a Closure so we can do the subselect:
$twitss = Twit::whereIn('user_id', function($query)
{
$query->select('follow_id')
->from('user_follows')
->where('user_id', '1');
})->get();
And finally we can pass in the current user to include the current user's posts:
$twits = Twit::whereIn('user_id', function($query)
{
$query->select('follow_id')
->from('user_follows')
->where('user_id', '1');
})->orWhere('user_id', '1')->get();
Now you should be returned a Collection of twits from the current user and all the users that the current user follows.
And finally you would just replace the 1 with Auth::user()->id to find the current user.
Hope that helps! :)

Resources