Cross relationship between models (high i lov level) - laravel

I have a few models and relationship. People belongs to city, city belongs to region, region belongs to country. How can I display every people from particular country.

I am assuming your models have relations defined already. You could use whereHas() and the model relationships in dot notation to get all the people of the city of the region of the country you're intersted in.
$people = People::whereHas('city.region', function($query) use ($countryId) {
return $query->where('regions.country_id', $countryId);
->get();

Related

Get Eloquent table data from a nested loop

I am working on a student consultancy project. In the website header's country option, I am showing the value as, when the country is clicked, it will show the subcontinent and countries under the subcontinent. However, there are some popular countries that students are familiar with but unfamiliar with their subcontinent. So that's why those countries will be created under the subcontinent. So, for example, Australia is in Oceania, but Australia is in the subcontinent.
The subcontinent is in one-to-many relations with the country, and countries are in one-to-many relations with the university. So if I create Australia, I have to add something in countries to find the university under Australia. So I am adding one country Australia under subcontinent Australia. That way, I can access the university.
However, the main problem is I don't want to show that in the header's country drop-down menu. So I am trying to select it differently in the controller, which subcontinent doesn't have the same country name under it. So I will pass it with a different variable.
Controller
$dis = '';
$concatenated = collect();
foreach ($divisions as $key => $value) {
$dis = DB::table('subcontinents')
->where('subcontinent_name', '!=', $value->country_name)->get();
foreach ($concatenated as $k => $val) {
if ($val->subcontinent_name != $dis->subcontinent_name)
$concatenated = $concatenated->concat($dis);
}
}
dd($concatenated);
I created the country as a division. I am selecting subcontinents where the name is not the same. It gives output like this: [output][1]. So I tried to concat once if the name didn't exist previously. Now it's showing a null value. How can I solve this? Any kind of idea will also be helpful.

Laravel Relationship with 4 Table

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();

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.

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