JOINS with Many to Many Relationship - Laravel - php

I have two tables in a many to many relationship countries and teams table. In my country table, there is president_id. Now i want to get teams that belong to that president_id using a join query but i am not able to achieve this.
How can i achieve selecting all teams belonging to a particular president?
PS: Newbie with laravel
Country
public function teams()
{
return $this->belongsToMany('App\Team');
->withTimestamps();
}
Team
public function countries()
{
return $this->belongsToMany('App\Country')
->withTimestamps();
}
Controller
$teams = Team::all()->with('countries')->where('president_id,1)->first();
$getTeams = $teams->pluck('id')->toArray();

Your can get all teams that has countries with some president_id like this:
$president_id = 1;
$teams = Team::whereHas('countries',function($q)use($president_id){
$q->where('president_id',$president_id);
})->get();

Related

Get only 3 records using with from many to many relationship Laravel

I'm using laravel 7 and
I have 3 tables shown below. I want first three students data instead of all student. tables have many to many relationship.
groups
id
name
students
id
name
group_student_pivot
group_id
student_id
created_at
I have below relationship in models
Groups model
public function students()
{
return $this->belongsToMany(Student::class,'group_student_pivot')->withPivot(['status'])->withTimestamps();
}
Student model
public function groups()
{
return $this->belongsToMany(Group::class,'group_student_pivot')->withPivot(['status'])->withTimestamps();
}
$groups = Group::whereIn('id',$groupIds)->with('students')->get();
In above query I want first 3 students data instead of all students.
You can get 3 records like this:
$groups = Group::whereIn('id',$groupIds)->with('students', function($q){
$q->take(3);
})->get();
You can use with and whereHas method
$groups = Group::with('students')->whereHas('students', function($q){
$q->take(3);
})->whereIn('id',$groupIds)->get();

Many to Many Relation with custom pivot table

I have 4 tables in project's database:
users (id, name)
teams (id, name)
team_members (id, user_id, team_id)
team_member_permissions (team_member_id, team_id)
I need to get user's teams. My current solution is to create teamMembers relationship in User model:
public function teamMembers()
{
return $this->hasMany(TeamMember::class);
}
members relationship in Team model:
public function members()
{
return $this->hasMany(TeamMember::class);
}
permissions relationship in TeamMember model:
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
But how can I optimise it? For example, to get all teams for users I need to use
Team::whereHas('teamMember', function($query) use ($user){
$query->where('user_id', $user->id);
})->paginate();
But how can I implement a relationship that will contains all user's teams to get user's teams in one string of code, like $user->teams?
I suggest you use many to many relation in regards to your team_members tables to explicitly mention as pivot.
User model:
public function teams()
{
return $this->belongsToMany(Team::class, 'team_members');
}
Team model:
public function users()
{
return $this->belongsToMany(User::class, 'team_members');
}
Since you want to use whereHas clause on teamMember table, I believe that you want to extract teams based on the fact that all teams belonging to that user based on team_members table.
So, You can specify the table name on many to many relation as above.
Now you can use
$user->teams

How to get all books from another table when using many to many relationship Laravel / Eloquent / Query builder

Let me explain the scenario.
i have tables:
competitions
id title body
then
books
id name user_id
then i have a pivot table to store participants
so
participants
id competition_id user_id
Now i have set some relationships for these models.
Competition model
public function participants()
{
return $this->belongsToMany('App\User');
}
User model
public function participatedCompetitions()
{
return $this->belongsToMany('App\Competition');
}
Now i am fetching one single competition and in that same query i need to fetch a list of books of the participants of that competition.
So how can i achieve this.
Thanks.
Here is how you get all the books:
$userIds = $competition->participant()->get()->pluck('id');
// $userIds is your collection of User Ids that is participant in that compititions.
$books = Book::whereIn('user_id',$userIds)->get();

Laravel Eloquent Relationship custom query

I have 2 tables: USERS and SUBJECTS
The relationship between USER and SUBJECT is many to many.
In the User.php and Subject.php models, I defined:
User.php
function subjects() { return $this->belongsToMany('App\User'); }
Subject.php
function users() { return $this->belongsToMany('App\Subject'); }
The pivot table is subject_user and it has 3 columns:
subject_id, user_id, finished
The finished value can only be between 0 and 1.
Now I know that when I want to select all the subjects that an user studied, I have to write $user->subjects.
But what if I want to select all the subjects that an user studied and the finished value in the pivot table is equal to 1?
You need to add "withPivot()" to your relationship definitions, like this:
function subjects() { return $this->belongsToMany('App\User')->withPivot('finished'); }
function users() { return $this->belongsToMany('App\Subject')->withPivot('finished'); }
Then you can do:
$user->subjects()->where('finished', 1)->get();
You will need to eager load that relationship and use the wherePivot method.
$user = User::with(['subjects' => function($q) {
$q->wherePivot('finished', 1);
}])->fine($user_id);

Laravel 4 - Sorting Data

I am building a website in Laravel 4. I have a table in my DB called Games which contains a list of games. By default, I am sorting these Games with:
$games = Game::orderBy('title', 'ASC')->paginate(20);
Users can select which Games they are currently playing. These records are stored in a table called Players which stores game_id and user_id.
A couple of relevant models I have created:
class Game extends Eloquent {
public function players()
{
return $this->hasMany('Player');
}
}
class User extends Eloquent {
public function players()
{
return $this->hasMany('Player');
}
}
class Player extends Eloquent {
public function game()
{
return $this->belongsTo('Game');
}
public function user()
{
return $this->belongsTo('User');
}
}
What I would like to do is, be able to sort my Games by most popular (most total players) so that the Games list can be viewed in this way. I have tried the following, but it was nothing more than a stab in the dark as I'm pretty new to PHP frameworks and Laravel.
$games = Game::orderBy(count($this->players), 'DESC')->paginate(20);
Obviously the count($this->players) is wrong, but I'm kinda stuck on this one.
Thanks. Hopefully that all makes sense!
:)
You need to JOIN the tables manually then SELECT COUNT(player.id), GROUP BY (game.id) and ORDER BY COUNT(player.id).
Your final query should look like this:
SELECT game.*, COUNT(player.id) AS players
FROM game
LEFT JOIN player
ON player.game_id = game.id
GROUP BY player.id
ORDER BY players
Generating this with Laravel query builder is pretty simple:
DB::table('game')
->leftJoin('player', 'player.game_id', '=', 'game.id')
->groupBy('player.id')
->orderBy(DB::raw('COUNT(player.id)'))
->select('game.*')
->get();
Note that we cannot alias the COUNT to players and we cannot use models (no way to JOIN).

Categories