Home > other >  Respresent two relationships in laravel using the same two models but with diferent uses
Respresent two relationships in laravel using the same two models but with diferent uses

Time:07-20

I have two models in laravel, the users model and the rooms model. Each user can belong to multiple rooms and each room haves multiple users inside.

I also want to save the user who created the room making a field called admin_id.

This creates two relationships, a many to many relationship (rooms and users) and a one to many relationship (the user and all the rooms that the user created)

My problem is that i don't know how to model this information, i tried to create a separate table named users_rooms and adding the id of the user that created the table as a foreign key inside the rooms table, but that messed up my model relationship functions.

 Schema::create('rooms', function (Blueprint $table) { //Rooms schema
        $table->id();
        $table->string('name');
        $table->unsignedBigInteger('admin_id');
        $table->timestamps();

        $table->foreign('admin_id')
        ->references('id')
        ->on('users')
        ->onDelete('cascade');
    });

 
Schema::create('users', function (Blueprint $table) {. //Users schema
        $table->id();
        $table->string('username');
        $table->string('email')->unique();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
        $table->boolean('connected')->default(0);
        $table->rememberToken();
        $table->timestamps();
    });

Schema::create('user_room', function (Blueprint $table) {
        $table->id();
        $table->timestamps();

        $table->unsignedBigInteger('user_id');
        $table->unsignedBigInteger('room_id');

        $table->foreign('user_id')
            ->references('id')
            ->on('users');

        $table->foreign('room_id')
            ->references('id')
            ->on('rooms');
    });


class Room extends Model
                           
{
    use HasFactory;  

    public function users(){
        return $this->belongsToMany(User::class,'user_room');
    }

    public function user(){
        return $this->belongsTo(User::class);
    }     
}


class User extends Authenticatable
{
    use HasFactory; 
                               /*The problem comes here, i don't know how to name the 
                               functions to represent the both relationships*/
    public function rooms(){
        return $this->belongsToMany(Room::class,'user_room');
    }

    public function rooms(){
        return $this->hasMany(Room::class);
    }
}

CodePudding user response:

First you need to specify the foreign key on the room model, as it is named admin_id.

class Room extends Model          
{
    public function user()
    {
        return $this->belongsTo(User::class, 'admin_id');
    }     
}

Naming of the relationship is not connected to the structure, so you can call it what you want, i would probably go with something related to the user is an admin.

class User extends Authenticatable
{
    public function administrativeRooms()
    {
        return $this->hasMany(Room::class);
    }
}

CodePudding user response:

// Add foreign key to the Room model

class Room extends Model          
{
    public function user()
    {
        return $this->belongsTo(User::class, 'admin_id');
    }     
}  

class User extends Authenticatable
{
   use HasFactory; 
       
   public function rooms(){
      return $this->belongsToMany(Room::class,'user_room');
   }

   // Then need to simply change method name rooms from something else
   // as shown below    
   public function roomsOwn(){
      return $this->hasMany(Room::class);
   }
}

Then you can use roomsOwn in eloquent with

// This will give you all users list with the rooms they have created
// and rented
User::with('roomsOwn', 'rooms')->get();

Tip

Whenever you are creating a pivot table (like here you have created user_room), try to use the name in alphabetic order room_user. This way Laravel automatically guesses the pivot table name and we do not need to specify in our query.

  • Related