В настоящее время я работаю с Laravel 5.8, и в моей базе данных есть таблица users
и таблица roles
, которые связаны отношением «многие ко многим». Мое намерение состоит в том, чтобы заполнить всю базу данных за один раз, используя php artisan migrate:fresh --seed
, однако сводная таблица role_user
всегда пуста, что предполагает, что что-то не так с подключением/синхронизацией. Я намерен реализовать больше отношений «многие ко многим», поэтому я хочу полностью понять заполнение этих отношений с помощью сеялок и фабрик.
Как я могу засеять отношения «многие ко многим» и быстро проверить, правильно ли они работают?
Модель пользователя:
class User extends Authenticatable
{
//Default variables generated by Laravel
public function roles()
{
return $this->belongsToMany('App\Role', 'role_user')->withTimestamps();
}
}
Образец для подражания:
class Role extends Model
{
public function users()
{
return $this->belongsToMany('App\User', 'role_user')->withTimestamps();
}
}
Миграция таблицы role_user:
public function up()
{
Schema::create('role_user', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('role_id');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->timestamps();
}
Ролевой сеятель:
public function run()
{
$role_user = new Role();
$role_user->role = 'user';
$role_user->save();
$role_admin = new Role();
$role_admin->role = 'admin';
$role_admin->save();
}
Сеялка пользователя:
public function run()
{
$faker = Faker\Factory::create();
$role_user = Role::where('role','=','user')->first();
$role_admin = Role::where('role','=','admin')->first();
//Generic user account for testing
$test_user = new User();
$test_user->username = 'user';
$test_user->email = '[email protected]';
$test_user->email_verified_at = now();
$test_user->password = 'user';
$test_user->remember_token = Str::random(10);
$test_user->save();
$test_user->roles()->attach($role_user);
//Generic admin account for testing
$test_admin = new User();
$test_admin->username = 'admin';
$test_admin->email = '[email protected]';
$test_admin->email_verified_at = now();
$test_admin->password = 'admin';
$test_admin->remember_token = Str::random(10);
$test_admin->save();
$test_admin->roles()->attach($role_admin);
}
Я просто вырезал несколько строк, чтобы сделать код кратким. :)
Если вы хотите использовать через factory,
Создайте UserFactory.php в папке фабрик
<?php
use App\User;
use Illuminate\Support\Str;
use Faker\Generator as Faker;
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/
$factory->define(App\User::class, function (Faker $faker) {
return [
'username' => $faker->name ,
'email' => $faker->unique()->safeEmail ,
'email_verified_at ' => Str::random(10),
'remember_token' => now(),
'password' => Hash::make('123456')
];
});
Затем создайте RoleUsersFactory.php
<?php
use App\User,App\Role,App\RoleUser;
use Illuminate\Support\Str;
use Faker\Generator as Faker;
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/
$factory->define(App\RoleUser::class, function (Faker $faker) {
return [
'role_id' => Role::all()->random()->id,
'user_id' => User::all()->random()->id,
];
});
Затем в вашем DatabaseSeeder.php Добавь это
factory(App\User::class, 50)->create()->each(function($u) {
$u->userroles()->save(factory(App\RoleUser::class)->make());
});
Еще одна вещь, которую вам нужно создать для модели RoleUser, и в модели User вы установили неверную связь role_user
, которая не существует в вашей таблице ролей.
надеюсь, это поможет
Эта модель должна расширять Model или Pivot?
Просто расширяет модель
Я не понимаю эту часть о неправильных отношениях role_user
. Я думал, что второй параметр используется для имени сводной таблицы. В документации role_user
оба слова в единственном числе являются соглашением об именах для сводных таблиц. Не могли бы Вы объяснить это мне?
Посмотрите на этот синтаксис return $this->hasMany('App\Comment', 'foreign_key', 'local_key');
Ссылка: laravel.com/docs/5.8/eloquent-relationships#один-ко-многим-инвеrse
1 проблема: Laravel задает 100 строк вместо 50. 2 проблема: заполняет role_id выше 2, и это не работает: 'role_id' => Role::where('id','<=','2')->get()->random()->id
. 3 проблема: это задает не уникальные идентификаторы пользователей.
Для чего нужен
$faker
? А по мне так нормально...