How do I access relation of a relation in laravel eloquent - laravel

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.

Related

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

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.

View data according to class and class group

I had an admin panel where 3 types of user are there Admin, Teacher and Student. Now I want that when student logged in he/she only see data uploaded by admin
According to his/her class and class group like class=10th and group=computer science. I have no idea how can i get this type of thing. I had used following code
$paper = Paper::where('paper_type','PaperSolution' && 'class',Auth::user()->class)->get();
this is not working properly as I am dumping data
dd($paper);
it is giving me null as answer.
you can use more granular wheres passed as array:
$query->where([
['column_1', '=', 'value_1'],
['column_2', '<>', 'value_2'],
[COLUMN, OPERATOR, VALUE],
...
])
Try this
$paper = Paper::where([['paper_type','PaperSolution'],['class', Auth::user()->class]])->get();
dd($paper);
OR
$paper = Paper::where([['paper_type','=','PaperSolution'],['class','=', Auth::user()->class]])->get();
dd($paper);
Reference for where query using array
ReferenceLink
Please refer to Laravel collection docs to correct syntax.
$paper = Paper::where('paper_type','PaperSolution')
->where('class', Auth::user()->class)
->get();
I did not exactly understand structure of your DB, but at first you need to have corresponding columns to then write any query. Your first option is uploaded by admin so in your uploads table (which is Paper model as I can see from your text) you should have something like uploader_role. Then you have student_class and student_group options. I want to get your attention in fact that this 2 options are users table columns NOT uploads (Paper). So you need to check some permissions of users, then get papers uploaded by admins. You can do that with middleware or just in your controller
$user = Auth::user();
if ($user->class == 10 && $user->group == 'computer_science') {
$papers = Paper::where('uploader_role', 'admin')
// you can add extra where options if that columns exist in papers table and you need to filter them also by class and group
->where( 'class_that_has_permissions', $user->class)
->where( 'group_that_has_permissions', $user->group)
->get();
return $papers;
}
abort(404);
Also be careful with columns that have name class that can return real user class name like App\User, try to use class_name or class_number.

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...

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