Laravel Many to Many Relationship ( hasMany or belongsToMany ) - php

I am currently building my first App with Laravel and have stumbled upon the problem that I dont know how to setup the relationship Many-to-Many between the Models (User and Group).
I've created a board in which I store the relationship between all users and the Group they are in.
My Problem is that I dont know how to acces and set this up in Laravel.
Im not sure whether I have to user hasMany or belongsToMany.
I am trying to find a method to add a User to Group, so that a new entry will be created in the UserGroups table.
My tables:
User
ID
Name
Email
Group
ID
Name
Creator_ID
UserGroup
User_ID
Group_ID
I appreciate any help, thanks!

If you want to create a many-to-many relationship, it should be belongsToMany, not hasMany.
In the Group model:
public function users()
{
return $this->belongsToMany(Group::class);
}
And in the User model:
public function groups()
{
return $this->belongsToMany(User::class);
}
The pivot table should be called group_user.
https://laravel.com/docs/5.4/eloquent-relationships#many-to-many

In the model class, use belongsToMany as demonstrated here: https://laravel.com/docs/5.4/eloquent-relationships#many-to-many
To add a user to a group, use attach(), as demonstrated here:
https://laravel.com/docs/5.4/eloquent-relationships#the-create-method (scroll to many to many relations)

Related

Laravel's relationship using Eloquent really correct?

I have a project running Laravel 5.5, and I have the following tables in the database.
USERS (
    ID,
    NAME,
    PERMISSION_ID
)
PERMISSIONS (
    ID,
    NAME
)
If I am not wrong, USERS relationship with PERMISSIONS is 1.1 (USERS has at least 1 permission and a maximum of 1), so it's a OneToOne relationship.
In my user model I made the following relationship.
class User extends Authenticatable
{
    public function permission () {
        return $this->hasOne('App\Models\Permission');
    }
}
But in this way Laravel/Eloquent looks for the relationship in the PERMISSIONS table. Generating a select similar to:
SELECT * FROM PERMISSIONS WHERE PERMISSIONS.USER_ID = 1
I have already consulted the Laravel documentation and saw that I can specify the ForeignKey and LocalKey in the hasOne method. This solves the relationship.
But is it really correct for Laravel/Eloquent by default to fetch the information in the PERMISSIONS table? The correct one would not be to look in the USERS table with PERMISSION_ID?
#Edit
Due to the response of Alexey Mezenin
I researched the difference between hasOne and belongsTo. And I found the following answer:
What is the difference between BelongsTo And HasOne in Laravel
From what I understood, when the foreign key is on the other table the correct one is to use hasOne.
When the foreign key is in the template's own table, the correct one is to use belongsTo.
I'll stay tuned in on these details next time, thanks Alexey Mezenin and jedrzej.kurylo
Your relationship is inverted, you're using hasOne() instead of belongsTo. Use this relationship in the User model:
public function permission()
{
return $this->belongsTo(Permission::class);
}
And in the Permission model you might want to add hasOne() relationship (in case if you would want to use it):
public function user()
{
return $this->hasOne(User::class);
}
But usually, the same permission can be used by many users. If this is the case, just change hasOne to hasMany.

Eloquent Relationships, linking of models (Laravel 5.4)

I'm kinda confused how the eloquent relationships works in Laravel 5.4.
I got a school model that has a "hasMany" relationship with my user model:
public function users()
{
return $this->hasMany('App\User');
}
The user is not required to be linked to a school though, so I haven't put the belongsTo (school) function on my user model.
How should I link the user to a school, when I create the user and how can I pull all users in a specific school into a view, for example?
If the user can only belong to one school, the most straightforward approach would be to add a school_id column to the users table. Since it's not required, you can allow for it to be null. This will allow you to run $school->users to retrieve a list of users for a given school.
I would also recommend adding the belongsTo relationship to the User model, so you can do $user->school to retrieve a user's school when applicable. It's okay that it'll be null for some users.

How do I access one model from another which don't have direct relationship?

I have an User model. Each user has certain grades and each grade has certain students.
User and Grade models have one-to-many relationship. Grade and Student models have one-to-many relationship too. But, User and Student models don't have any relationship.
Once User is logged in, he should be able to search all students that belongs to the user.
Do I have to create relationship between these two models to?
If I understand the question correctly, a user has multiple students, so what I'd do is create a one-to-many relationship between them like this:
//User.php
public function students()
{
return $this->hasMany(Student::class);
}
//Student.php
public function user()
{
return $this->belongsToOne(User::class);
}
This would allow you to pick up a users students by doing: $students = $user->students Note: I didn't use () here. If you were to execute $students = $user->students() you'd end up with a query builder object.

Nested one to many relationships in Eloquent

Let's say I have three models with this relationsship
USER
hasMany (app/organisation)
ORGANISATION
hasMany (app/order)
ORDER
For one level I could just go
user->organisations()->get()
And get all the organisations tied to the user. But every organisation also have 0..many ORDER entities. So I want to do this:
user->organisations()->orders()->get()
To get a list of all the orders from all the organisations from a certain user. Is that possible this way?
What you can simply do is implement hasManyThrough() relationship on User model.
public function orders()
{
return $this->hasManyThrough(Order::class, organisation::class);
}
then you can query like,
$user->orders()->get();

Laravel 5 database relation type

I would like to use Laravel 5 Models to retrieve a relationship, but i dont know which relation type i should use and how to implement it.
i have 4 database tables:
Users
Roles
Permissions
role_permission
i need to retrieve all the permissions for a "User" based on its "role_id" column.
I've created 3 models:
User
Role
Permission
The database table "users" holds 2 columns:
id
role_id
The database table "roles" holds 2 columns
id
name
The database table "permissions" holds 2 columns
id
name
The database table "role_permission" holds 3 columns that defines which Role is associated to which Permission.
role_id
permission_id
flag
What i want to achieve is the following syntax:
$user->role // Get the associated "Role"
$user->role->permissions // Get the associated permissions for a "Role"
App\Role::find(1)->permissions // Get the associated permissions for a "Role"
i did read the Laravel documentation about model relations but i really dont get it. Does someone understand what i'm trying to achieve and how to implement it in the Models? maybe with some simpel code examples so i can understand the relations and how they work?
Thanks in advance.
The way that you have your database defined, you have defined the following relationships: a one-to-many between role and users, and a many-to-many between roles and permissions. It can also be stated that a role has many users, a user belongs to a role, a role has many permissions, and a permission has many roles.
In Laravel, one-to-one relationships are modeled using a hasOne/belongsTo set, one-to-many relationships are modeled using a hasMany/belongsTo set, and many-to-many relationships are modeled using a belongsToMany/belongsToMany set.
The relationships are defined in the models below:
User:
Since the users table contains the foreign key to the roles table (role_id), the User model is on the belongsTo side of the one-to-one/one-to-many relationship.
class User extends Model {
public function role() {
return $this->belongsTo('\App\Role');
}
}
Role/Permission:
The many-to-many with permissions is done by both models having a belongsToMany relationship. The Laravel convention for the pivot table name is the combination of the singular table names, in alphabetical order, with an underscore separator, so it should be 'permission_role'. Since the pivot table name doesn't follow convention, it must be specified in the relationship definition. Also, since you have an extra field on the pivot table, you need to specify access to that field with the withPivot() method on the relationship.
class Role extends Model {
public function users() {
return $this->hasMany('\App\User');
}
public function permissions() {
return $this->belongsToMany('\App\Permission', 'role_permission')->withPivot('flag');
}
}
class Permission extends Model {
public function roles() {
return $this->belongsToMany('\App\Role', 'role_permission')->withPivot('flag');
}
}

Categories