Проблемы с ролями в laravel

Обратите внимание: я новичок в laravel и программировании в целом.

Итак, я работаю над настройкой ролевой системы в моем проекте laravel, и я последовал руководству и сделал все то же самое. Моя проблема в том, что при регистрации он должен зарегистрировать нового пользователя с ролью «Пользователь», а этого не происходит. Кроме того, мое заполнение базы данных не сохраняет идентификатор роли для моих пользователей.

Перенос таблицы "Мои пользователи"

class CreateUsersTable extends Migration
{
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
            $table->unsignedBigInteger('roles_id')->nullable();
            $table->foreign('roles_id')->references('id')->on('roles');
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
    }
}

Перенос таблицы моих ролей

class CreateRolesTable extends Migration
{
    public function up()
    {
        Schema::create('roles', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
        });
    }

    public function down()
    {
        Schema::dropIfExists('roles');
    }
}

Перенос моей таблицы role_user:

class CreateRoleUserTable extends Migration
{

    public function up()
    {
        Schema::create('role_user', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->bigInteger('role_id')->unsigned();
            $table->bigInteger('user_id')->unsigned();
        });
    }

    public function down()
    {
        Schema::dropIfExists('role_user');
    }
}

My DataBaseSeeder:

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        // Role comes before User seeder here.
        $this->call(RoleTableSeeder::class);
        // User seeder will use the roles above created.
        $this->call(UserTableSeeder::class);
    }
}

RoleTableSeeder

use Illuminate\Database\Seeder;
use App\Role;

class RoleTableSeeder extends Seeder
{
    public function run()
    {
        $role_worker = new Role();
        $role_worker->name = 'worker';
        $role_worker->save();

        $role_admin = new Role();
        $role_admin->name = 'admin';
        $role_admin->save();

        $role_user = new Role();
        $role_user->name = 'user';
        $role_user->save();
    }
}

UserTableSeeder

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
use App\Role;
use App\User;

class UserTableSeeder extends Seeder
{
    public function run()
    {
        $role_worker = Role::where('name', 'worker')->first();
        $role_admin  = Role::where('name', 'admin')->first();
        $role_user  = Role::where('name', 'user')->first();

        $worker = new User();
        $worker->name = 'Worker User';
        $worker->email = '[email protected]';
        $worker->password = Hash::make('password');
        $worker->save();
        $worker->roles()->attach($role_worker);

        $admin = new User();
        $admin->name = 'Admin user';
        $admin->email = '[email protected]';
        $admin->password = Hash::make('password');
        $admin->save();
        $admin->roles()->attach($role_admin);

        $user = new User();
        $user->name = 'Regular user';
        $user->email = '[email protected]';
        $user->password = Hash::make('password');
        $user->save();
        $user->roles()->attach($role_user);
    }
}

Таблицы после переноса / заполнения

Итак, моя проблема в том, что при регистрации он должен зарегистрировать нового пользователя с ролью «Пользователь», а этого не происходит. Кроме того, при заполнении базы данных моим пользователям не сохраняются никакие role_id.


person svw055    schedule 03.12.2019    source источник
comment
Есть ли у вас отношения на самих моделях?   -  person Alec Joy    schedule 04.12.2019
comment
@AlecJoy Судя по скриншотам, да, так как $user->roles()->attach() потерпел бы неудачу, если бы они не были.   -  person Tim Lewis    schedule 04.12.2019


Ответы (1)


У вас есть стержневые отношения; нет необходимости помещать столбец roles_id для ваших пользователей. Удалите эти строки из своей миграции:

CreateUsersTable

// $table->unsignedBigInteger('roles_id')->nullable();
// $table->foreign('roles_id')->references('id')->on('roles');

Все остальное выглядит хорошо; ваши таблицы roles и users заполняются, и сводная таблица устанавливает правильные значения для user_id и role_id. Теперь вы получите доступ к ролям пользователя через

$user->roles
// Should return a `Collection` of roles, based on the number of records in `role_user`

Кстати, у вас обычно нет автоматически увеличивающегося идентификатора в pivot таблице, поскольку данные постоянно меняются, и вы вряд ли будете ссылаться на role_user.id в любой момент, поэтому вы также можете отбросить эту строку:

CreateRoleUserTable

// $table->bigIncrements('id');

Изменить: более серьезной проблемой здесь является фундаментальное непонимание того, как работают отношения pivot и many-to-many (и это нормально, вы сказали, что новичок в Laravel и программировании).

Я считаю, что вы пытаетесь установить roles_id на users на role_user.id, но это в корне неверно. Этот тип отношений работает не так. Он использует промежуточную таблицу role_user, в которой есть user_id и role_id, чтобы связать множество экземпляров users со многими экземплярами roles.

Если бы вы установили roles_id на users, вы могли бы иметь только один role, после чего он перестал бы быть many-to-many и стал бы простой связью между users и roles, что сделало бы role_user таблицу совершенно ненужной.

person Tim Lewis    schedule 03.12.2019
comment
Спасибо за очень долгий ответ! Вы правы, мне не хватает фундаментального понимания pivot и отношений «многие ко многим», эта концепция для меня нова. - person svw055; 04.12.2019
comment
Без проблем! И снова, я надеюсь, что это не показалось подлым; Я не имел в виду это как нечто отрицательное; сначала все борются с новыми концепциями. В конце концов, вы приобретете навыки, и на самом деле вы были довольно близки в этой первоначальной попытке. Продолжайте хорошую работу! - person Tim Lewis; 04.12.2019
comment
Вы не показались злым, я очень ценю ваш отзыв, спасибо! - person svw055; 04.12.2019