Laravel 9.* belongsToMany - laravel

I have DB structure:
user
user_id
office
office_id
property
property_id
office_user
office_user_id
office_id
user_id
office_user_property
office_user_id
property_id
Is there way to acess to Property model from User model via belongsToMany?

What you are looking for is the hasManyThrough
(https://laravel.com/docs/9.x/eloquent-relationships#has-many-through), but it only work for one connection in between, and you have two.
What you could do is define a hasManyThrough relation between user and office_user_property and define a hasOne relation between office_user_property and property

belongsToMany refers to Many To Many. This relationship for your case defines that has many properties, while a property is owened by many users. In a nutshell three database tables can be used to define this relationship. properties table, users table, and user_property table. where the user_property table contains user_id and property_id columns.
In the user model, the relationship can be defined as:
/.../
public funciton properties(){
return $this->belonsToMany('App\Property');
}
To access properties for a user:
$user = App\User::find(1);
foreach ($user->properties as $property) {
//
}
Ref: Laravel 5.2 Docs

Related

Laravel: how to sort a collection with hasMany field

I have five tables:
details having fields id, name and has hasMany relation with contributions.
purpose having fields id, name and has hasMany relation with contributions.
period having fields id, name and has hasMany relation with contributions.
user having fields id, name and has hasMany relation with contributions.
and
contributions having id, amount and "belongsTo" relation with user_id, detail_id, purpose_id, period_id
Now, I want to get all contributions of a specific user (filtered by user_id) and then sort the result by period.name, detail.name and purpose.name.
Any suggestions?
The question has been identified as possible duplicate of Laravel orderBy on a relationship . However there is a basic difference.
there, there is relation between user and comment & user and post. however in my case, there isn't any relation between user and details/purposes/periods tables.
<?php
class User
{
public function comments()
{
return $this->hasMany('Comment');
}
}
is possible in that case, but by same analogy, in my case, class User doesn't have any details() function to get hasMany relations. My user has relation with only contributions table and contributions table has relations with details purpose etc tables.
hope I am able to clarify the difference.

Invalid argument supplied for foreach() in laravel when use Eloquent: Relationships

I wanna get the class name of a user via the user ID. When I input the ID of a user so I will wanna get the class name. I have three tables such as users table, classes table, and class_users table. The class_users table is born from two users table and classes table.
A users table has an id, name, email, password.
A classes table has an id, class_code, class_name.
A class_users table has an id, class_id, user_id
And this problem relates to Eloquent Relationships.
Thank you for help.
My Route:
Route::get('/find_classes/{id}','StudentController#find_classes');
My Controller function:
public function find_classes($id)
{
$users = User::find($id);
foreach($users->classes as $class)
{
echo $class->name . '<br';
dd($class);
}
}
My User Model:
public function classes()
{
return $this->belongsTo('App\Classes','class_users','user_id','class_id');
}
Looks like you might have the wrong relationship set up on your User model. You have a one to many set up, but your DB is setup to handle a many to many. I suggest you change your User model relationship:
public function classes()
{
return $this->belongsToMany('App\Classes');
}
Note, you may need to name the FK on that relation, as I see you have class_id on the table, but your actual class is named 'Classes'. Check through your relationships to ensure this is explicit on the FK where it doesn't follow Laravel convention exactly.
With this relationship, your foreach loop should work. It would be a good idea for efficiency, as mare96 noted, to eager load the classes on the $users collection when you query:
$users = User::with('classes')->find($id);

Is it possible to dynamically set model for Eloquent Relationships?

I have 2 user roles. In database I have own profile tables for both of roles ( model_profiles and client_profiles). Is there any way to set related Profile model dynamically? I've tried this:
//User model:
public function profile(){
return $this->role == 'model' ? $this->hasOne('App\Models\Model\Profile') : $this->hasOne('App\Models\Client\Profile');
}
But in this case I can't use some Eloquent methods like User::with('profile')->whereIn('id', [1,2,3])->get(); because $this->role is null until user model is loaded.
Is there any way to use Profile model based on user role and don't lose any Eloquent query methods?
You can use Polymorphic relationships (More Information)

Mutli relationships with Eloquent and Laravel

I have 6 tables:
permissions:
id
permission_name
roles:
id
role_name
user_roles:
id
user_id
role_id
user_permissions:
id
user_id
permission_id
role_permissions:
id
role_id
permission_id
users:
id
username
email
Now I like to add a custom function into my Eloquent model for permissions named getUsersWithPermission().
Now it is possible that user has the permission by the role he has given (user table join on user_roles, join that table on role_permissions and last that table join on permissions.
Or the user has a specific permission set in the user_permissions table (join user_permissions table on user table and join the permissions table on the user_permissions table)
How can I create a Eloquent model function that returns all the users with a specific permission say: "notification.error.process" where that is the permission name
A hasMany doesn't quite do what I want (and I cannot define multi tables in there). I am using Laravel 5.6.
If you defined your many-to-many relations correctly (User-Permission and User-Role-Permission), the following should do the trick:
$permissionName = 'notification.error.process';
$usersWithPermission = User::whereHas('permissions', function($query) use ($permissionName) {
$query->whereName($permissionName);
})->orWhereHas('roles.permissions', function($query) use ($permissionName) {
$query->whereName($permissionName);
})->get();
Try to understand your table structure using this ER diagram.
TO handle this situation, You may create 3 'Eloquent Models'
User
Role
Permission
in every model you may create belongsToMany() relationship to each other models.
one example, On 'User Model'
public function permissions()
{
// need to define any other differences in your tables foreign keys as 2nd, 3rd parameters and so on.
return $this->belongsToMany(Permission::class);
}
Now you need to get all the users 'whom has a role which has the privilege' OR 'whom directly has the privilege.
to do so.
$users = User::whereHas('privileges', function($query) {
$query->where('permission_name', 'notification.error.process');
})->orWhereHas('roles.permissions', function($query) {
$query->where('permission_name', 'notification.error.process');
})->get();
I hope you will get an idea. your code may be slightly different from mine. but this is the concept.

Laravel and pivot table to relate different model

I'm wondering how, but it's bit confusing.
I have fine belongs to many relation between users and groups tables as well as appropriate models for all of that.
But i also have table students, where not all users are student so i students table i maintain user_id field.
My question would be: Can i use pivot table "group_user" for relations between student and group model, in students table i have "user_id" field? and how?
I tried something like
public function students()
{
return $this->belongsToMany('Student','group_user','group_id','user_id');
{
but i don't see the way how to tell eloquent not to take students.id but to take students.user_id???
Assuming these relations:
Subject belongsTo Group
Group belongsToMany User
User hasOne Student
you can easily do this:
$subject = Subject::find($someId);
// of course for multiple subject use eager loading:
// $subjects = Subject::with('group.users.student')->get();
$users = $subject->group->users; // related users
foreach ($users as $user)
{
$user->student; // null|student model
}

Resources