I have relationship between users and i want to search and get collection from connected users. Example:
Users:
ID: 1 | Nikola - he is TRAINER
ID: 2 | Test - he is his client
ClientTrainer Table:
trainer_id | client_id | status
1 | 2 | 1
When trainer search for specific users, i want to search only users who has status 1 and have relationship between them.
This is my current code:
if(isset($_GET['type'])){
$names = explode(" ", $_GET['type']);
$klijenti = User::where(function($query) use ($names) {
$query->whereIn('name', $names);
$query->orWhere(function($query) use ($names) {
$query->whereIn('surname', $names);
});
})->orderBy("last_seen","DESC")->get();
print_r($klijenti);
if(empty($_GET['type'])){
$klijenti = $user->allclients;
}
}
I don't know if I fully understand your requirement, but here is one solution that utilizes relationships:
Add this to your User Model. This assumes that your "ClientTrainer" Table is called client_trainers.
public function clients()
{
return $this->belongsToMany('App\User', 'client_trainers', 'trainer_id', 'client_id')
->wherePivot('status', 1);
}
Option 1
Now you should be able to perform queries like this, assuming that Auth::user() returns the currently logged in trainer:
$clients = Auth::user()->clients()->whereIn('name', $names)
->orWhereIn('surname', $names)
->orderBy("last_seen","DESC")->get();
Or to get all the clients of a single trainer just do something like
$clients = Auth::user()->clients()->get();
Option 2
If you want to search independently of a single trainer, you can do something like this:
$clients = User::has('clients')
->whereIn('name', $names)
->orWhereIn('surname', $names)
->orderBy("last_seen","DESC")->get();
The first part User::has('clients') should only return Users that have at least on client with status = 1 in the client_trainers table.
Related
In laravel9 I have created following tables
users (its laravel auth ui)
tournamnets
matches (in matches i have column "name")
registrations (in registration I have relation with users and one column status_id Bydefault its 0 and relation with matches is hasmany and belongsTo)
Note: match id is linked with hasmany and belongsto relation
Note: registrations and tournamnets have Pivot table which is reg_tours
Column names are tournaments_id and registrations_id.
Now I need with user registered for the specific tournament and registrations status is 0 the show {you are registered} in that specific tournament and if with user registered for the specific tournament and that registrations status is any match id which is linked with belongs to relation then show that match name
Tournament Controller
public function singleTournament($id) {
$game = Game::all();
$data = Tournament::find($id);
if ($data->teamsize == 1) {
$data->teamsize = "Solo";
} elseif ($data->teamsize == 2) {
$data->teamsize = "Duo";
} elseif ($data->teamsize == 4) {
$data->teamsize = "Squad";
}
return view('site.tournament',compact('data','game'));
}
Thank You!
I need to show status for specific tournament to specific user
you can add initialize for the status variable before
Im new to laravel db query. I have problem when want to query.
I have two table customer and history. In history it have few column which are customer_id, activity (purchase,buyback), product_type(gold,silver) and quantity. Currently I want to retrieve balance for each of customer. To get balance, purchase - buyback.
-> customer_id | gold_balance | silver_balance
Here I attach two part of table and code to be review.
Thanks in advance.
You should create a hasMany relationship between Customer and History (maybe called histories) and create a custom attribute that loops through histories and add/subtract amount.
Something like this (not tested):
class Customer {
public function histories() {
return $this->hasMany(History::class);
}
public function getBalanceAttribute() {
return $this->histories->reduce(function($total, $current) {
$grossAmount = $current->amount * $current->quantity;
return $current->activity === 'purchase' ? $total - grossAmount : $total + grossAmount;
}, 0;
}
}
I have a many to many relationship between users and achievements. Table layout is similar to this.
users
-id
-first_name
-last_name
-email
acheivements
-id
-type-name
-description
achievement_user
-id
-acievement_id
-user_id
-is_complete (boolean)
-percentage_complete (integer)
-completed_at
I can get the bulk of the stuff I want such as all achievements with type = badge for a user that are in the pivot table. I can also get a list of all the achievements that have type = badge. Where I am stuck is trying to get all achievements with type = badge along with is_complete, percentage_complete, completed_at for that given user. So if there are 8 total badges and they have started 3 of them I would want to return 8 records where 3 of them would have the information from the pivot table. I know I could grab all badges and loop through them to add on additional information but I know there is a eloquent way that would be easier.
Thank for any help.
This is in response to you recent comment.
To achieve what you want, I have introduced a new method on the User model called achievementsblock, which uses php array_map method.
I have not tested the code, but you should get the idea.
//in User model
public function achievements()
{
return $this->belongsToMany('App\Achievements')->withPivot('is_complete', 'percentage_complete', 'completed_at');
}
//in User model
public function achievementsblock()
{
$all_achievements = Achievement::all();
return array_map(function($temp_achievement){
$achievement_ids = $this->achievements()->pluck('id');
$new_temp = new \stdClass();
$new_temp->type_name = $temp_achievement->type_name;
$new_temp->description = $temp_achievement->description;
if(in_array($temp_achievement->id, $achievement_ids)){
$user_achievement = $this->achievements()->where("achievements.id","=",$temp_achievement->id)->first();
$new_temp->is_complete = $user_achievement->is_complete;
$new_temp->percentage_complete = $user_achievement->percentage_complete;
$new_temp->completed_at = $user_achievement->completed_at;
}
else {
$new_temp->is_complete = 0;
$new_temp->percentage_complete = 0;
$new_temp->completed_at = null;
}
return $new_temp;
}, $all_achievements);
}
In your controllers, you can get the achievementsblock for a user as follows:
$user_achievement_blocks = User::first()->achievementsblock();
On your belongsToMany relationship, use the withPivot function as follows:
//in User model
public function acheivements()
{
return $this->belongsToMany('App\Acheivement')->withPivot('is_complete', 'percentage_complete', 'completed_at');
}
//in Acheivement model
public function users()
{
return $this->belongsToMany('App\User')->withPivot('is_complete', 'percentage_complete', 'completed_at');
}
You need to learn about whereHas method which lets you query on relationship while getting results
In User model
// create achievements relationship
public function achievements()
{
return $this->belongsToMany(Achievement::class)
->withPivot('is_complete', 'percentage_complete', 'completed_at');
}
//then query it like shown below.
$achievements= $user->achievements;
Read more here
I want to get the projects by the Auth::user() and company_id. I created the following:
Database:
projects:
- id
- name
- company_id
project_users:
- id
- project_id
- user_id
users:
- id
- name
- email
companies:
- id
- name
So I want to get the current user projects which belongs to company_id.
I tried the following with User Modal -> return $this->hasManyThrough('App\ProjectUsers', 'App\Project'). $user->projects->where('company_id', 1) but it returns all the data (also with company_id 2,3,4 etc).
I'm looking for a solution which can filter the projects with company_id 1 out of the query.
You have to create function in model of user
public function projectusers() {
return $this->hasMany('App\Models\project_users', 'projectID')->with('companies');
}
now create function in model projects
public function companies() {
return $this->hasMany('App\Models\companies','id', 'company_id');
}
If you are trying to limit a relation based on the results of another relation, then you need to use whereHas.
Also if you want to get the projects by some condition, I find its often most helpful to start there, with the projects.
$projects = App\Project::whereHas('company', function($q) use ($company_id) {
$q->where('id', $company_id);
})->with('users')->get();
This will grab only the projects belonging to a certain company and also eager load the users.
As you are looping, then you can get the count of the users using the relation.
foreach ($projects as $project) {
echo 'Num User: '.$project->users->count();
}
I have a many to many relationship between users and images.
User Model
public function image()
{
return $this->belongsToMany('\App\Image');
}
Image Model
public function user()
{
return $this->belongsToMany('\App\User');
}
Tables
users
id | name
images
id | url
image_user
id | image_id | user_id
When a user 'favourites' an image, it's stored in the pivot table.
id | image_id | user_id
1 1 1
2 2 1
3 1 2
I need a count of each images favourites.
I try something like:
Image::with('user')->find(1)->count();
But this counts the number of users, not the number of favourites.
Ideally I would like to return all of the image data along with a count of the user data - how can I do this?
You can do this:
$image = Image::with('user')->find(1) // Get the image with user eager loading
$image->name; // Access any attribute
$image->users->count(); // Get the user count
You can even add a few lines in your Image model to create a "custom" attribute:
public function getFavoritesAttribute()
{
return count($this->users);
}
And then use it like this:
$image->favourites;
There is a more detailed solution here:
Laravel many to many loading related models with count