Laravel Relationship with 4 Table - laravel

I've got 4 tables:
users
teams
locations
users_teams
my teams table has relationship with locations. (it has location_id field)
users and teams have belongsToMany relationship with users_teams.
users doesn't have directly relationship with locations.
But I need to get coaches in this location.
It means; "get me all coaches; which are belongs to teams of that location"
But couldnt move any to make this.
How can this be possible?
how my "coaches" function of my "Location" model?

If your relationships are set up correctly, and assuming you have an enum column named type with coach as a possible value, you should be able to do something like this:
$coaches = User::where('type', 'coach')
->whereHas('teams.locations', function($query)
{
$query->where('name', 'some place');
})->get();

Related

use or and whereHas in eloquent

I have an orders table which contains 2 columns, user_id and unregistered_address. One of the columns has to be null as the user can either be registered with an address, or unregistered and just has address details.
Both user.address and unregistered_address are linked to a city. (user.address.city & unregistered_address.city)
I want to get the orders, for a specific cities, for both registered users and unregistered users. I am using eloquent's whereHas but it seems that when one of the two columns is null i get no results. This is my code:
$orders = Order::whereHas('user.address', function($query) use ($cityIds){
$query->whereIn('city_id', $cityIds);
})
->whereHas('unregisteredAddress', function ($query) use ($cityIds){
$query->whereIn('city_id', $cityIds);
})-> with(['user.address','unregisteredAddress'])->get();
Can anyone help? thanks.

How do I access relation of a relation in laravel eloquent

I have a user, group, group profile, group members, table.
Relation:
users belongs to many groups,
groups belongs to many users (name of function is groupMembers),
group has one groupProfile
I want to display the groups of a certain user with group profile and group member count.
Currently, I have this:
$userGroups = UserView::findOrFail($userId)
->groups()
->get();
I also have this: it return everything I want, except the fact that it is not user specific. (it returns all groups)
$userGroups = GroupView::with(['groupProfile'])
->withCount('groupMembers as groupMemberCount')
->get();
$userGroups = UserView::findOrFail($userId)
->groups()
->with(['groupProfile'])
->withCount('groupMembers as groupMemberCount')
->get()
Laravel relations return a query builder (if you call the function instead of the property) this means anything you can do with a collection of models you can do the same with the collection of related models.

show rows with a relation before in Laravel

in a Laravel application, I have a list of companies. Some of those are related to a subscriptions table in a 1 x n relation.
I want to order the companies in a way that the ones which have a subscription appear before the ones which have no subscription using just one db query.
Any idea is much appreciated!
thanks!
Laravel uses separate queries to eager load relationships. So if you want to do this you will need to join the tables and order by...
Something in the form...
$companies = App\Companies::join('subscriptions as sub', 'sub.company_id', '=', 'company.id')
->orderBy('sub.somefield', 'DESC')
->select(what you need)
->with('if you need the relation data');
You know you can also only query those records that have a relationship with
$companies = App\Companies::has('subscription')->get();
Maybe that is all you need... and
$companies = App\Companies::doesntHave('subscription')->get();
... returns the opposite where the company has no subscription...

how do I query this relation with eloquent

I'm using Laravel and eloquent obviously.
I have 4 models and tables.
1 => city
2 => location
3 => venue
4 => tag
now bear with me to describe relationship.
a city has many locations and a location belongs to a city.
a location belongs to a venue and a venue has one location.
a venue belongs to many tags and a tag belongs to many venue (Many to many relationship)
Here are the query I wanna executed.
given A city, how can I filter venues of that city based on tags.
example: for city Austin I wanna get venues that have tag "special".
and Also, how many queries are executed for perform this task.Is it efficient to perform this kind of task with this database model.
I tried to be as explicit as possible but if some parts seems vague for you, please don't hesitate to ask.
thanks
Eloquent query below filters result based on relationship:
$venues = Venue::whereHas('location', function($query) use ($city) {
$query->where('city_id',$city->id);
})->get();

Laravel Many to Many - 3 models

Some help with many to many relationships in Laravel:
Using the example for roles and users - basically:
a table for all the roles
a table for the users
and table with user_id and role_id.
I want to add to the third table, eg Year. basically the pivot table will have user_id, role_id and year_id.
I want to be able to make a query to pull for example all users assigned a specific role in a specific year. Eg All users with role_id = 2, and year_id = 1.
Any help will be appreciated
Before answering, I would like to suggest you not to put year on database like this.
All your tables should have created_at and updated_at which should be enough for that.
To filter users like you want. You could do this:
// This queries all users that were assigned to 'admin' role within 2013.
User::join('role_users', 'role_users.user_id', '=', 'users.id')
->join('roles', 'roles.id', '=', 'role_users.role_id')
->where('roles.name', '=', 'admin')
->where(DB::raw('YEAR(role_users.created_at)', '=', '2013')
->get();
This example may not be the precise query you are looking for, but should be enough for you to come up with it.
The best way to achieve a three way relation with Eloquent is to create a model for the table representing this relation. Pivot tables is meant to be used for two way relations.
You could have then a table called roles_users_year which could have data related to this 3 way relation like a timestamp or whatever...
A very late answer to a very old question, but Laravel has supported additional intermediate (pivot) table columns of at least Laravel 5.1 judging from the documentation, which hasn't changed at least through Laravel 6.x.
You can describe these extra columns when defining your many-to-many relationship:
return $this->belongsToMany(Role::class)->withPivot('column1', 'column2');
or in your case, the below would also do the job:
return $this->belongsToMany(Role::class)->withTimestamps();
which you can then access via the pivot attribute on your model:
$user = User::find(1);
foreach ($user->roles as $role) {
echo $role->pivot->created_at;
}
Note that the pivot attribute is on the distant relationship model (a single Role) and not on the relationship itself.
To get all the Roles assigned to Users in any given year, you might create a special relationship:
// User.php
public function rolesInYear($year) {
return $this->belongsToMany(Role::class)
->wherePivot('created_at', '>=', Carbon::create($year))
->wherePivot('created_at', '<', Carbon::create($year + 1));
}

Resources