Laravel Eloquent多表关联迁移与填充问题求助
Laravel 填充器与工厂关联关系构建问题
刚接触Laravel,在使用数据库填充器(Seeder)和工厂(Factory)构建正确的关联关系时遇到了问题。
创建了四张表:Users、Projekts、Posts、Projekt_User_Pivots。
需求逻辑为:每个Projekt可以关联多个User,每个User可以关联多个Projekt和Post;需要仅展示某个项目内、属于该项目用户的Post。
尝试用填充器和工厂填充数据库,但无法通过工厂建立正确的主键关联,目前只能反复运行填充操作才偶尔成功,这显然不合理,希望得到帮助。
模型代码
Post.php
<?php namespace App\Models; use App\Models\User; use App\Models\Projekt; use Illuminate\Database\Eloquent\Model; use SebastianBergmann\CodeUnit\FunctionUnit; use Illuminate\Database\Eloquent\Factories\HasFactory; class Post extends Model { use HasFactory; public function user() { return $this->belongsTo(User::class); } }
Projekt.php
<?php namespace App\Models; use App\Models\Post; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Factories\HasFactory; class Projekt extends Model { use HasFactory; public function user() { return $this->belongsTo(User::class); } public function projektuserpivot() { return $this->hasMany(ProjektUserPivot::class); } }
ProjektUserPivot.php
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class ProjektUserPivot extends Model { use HasFactory; protected $primaryKey = ['user_id', 'projekt_id']; public $incrementing = false; public function user() { return $this->belongsTo(User::class); } public function projekt() { return $this->belongsTo(Projekt::class); } }
User.php
<?php namespace App\Models; // use Illuminate\Contracts\Auth\MustVerifyEmail; use App\Models\Post; use App\Models\Projekt; use Laravel\Sanctum\HasApiTokens; use Illuminate\Notifications\Notifiable; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable; /** * The attributes that are mass assignable. * * @var array<int, string> */ protected $fillable = [ 'name', 'email', 'password', ]; /** * The attributes that should be hidden for serialization. * * @var array<int, string> */ protected $hidden = [ 'password', 'remember_token', ]; /** * The attributes that should be cast. * * @var array<string, string> */ protected $casts = [ 'email_verified_at' => 'datetime', ]; public function post() { return $this->hasMany(Post::class); } public function projekt() { return $this->hasMany(Projekt::class); } public function projektuserpivot() { return $this->hasMany(ProjektUserPivot::class); } }
工厂代码
PostFactory.php
<?php namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; use Spatie\LaravelIgnition\Support\Composer\FakeComposer; /** * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Post> */ class PostFactory extends Factory { /** * Define the model's default state. * * @return array<string, mixed> */ public function definition() { return [ 'user_id' => $this->faker->numberBetween(0,999), 'title' => $this->faker->realTextBetween(10, 50), 'body' => $this->faker->realTextBetween(800, 1400), ]; } }
ProjektFactory.php
<?php namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; /** * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Projekt> */ class ProjektFactory extends Factory { /** * Define the model's default state. * * @return array<string, mixed> */ public function definition() { return [ 'name' => $this->faker->realTextBetween(10, 20), 'user_id' => $this->faker->numberBetween(1,999), ]; } }
ProjektUserPivotFactory.php
<?php namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; /** * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\ProjektUserPivot> */ class ProjektUserPivotFactory extends Factory { /** * Define the model's default state. * * @return array<string, mixed> */ public function definition() { return [ 'user_id' => $this->faker->numberBetween(1,999), 'projekt_id' => $this->faker->numberBetween(1,20), ]; } }
UserFactory.php
<?php namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Support\Str; /** * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User> */ class UserFactory extends Factory { /** * Define the model's default state. * * @return array<string, mixed> */ public function definition() { return [ 'name' => fake()->name(), 'email' => fake()->unique()->safeEmail(), 'email_verified_at' => now(), 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 'remember_token' => Str::random(10), ]; } /** * Indicate that the model's email address should be unverified. * * @return static */ public function unverified() { return $this->state(fn (array $attributes) => [ 'email_verified_at' => null, ]); } }
迁移代码
2014_10_12_000000_create_users_table.php
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('users'); } };
2022_12_08_154030_create_projekts_table.php
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('projekts', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('user_id'); $table->string('name'); $table->timestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('projekts'); } };
2022_12_08_154042_create_posts_table.php
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('posts', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('user_id'); $table->string('title'); $table->text('body'); $table->timestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('posts'); } };
2022_12_09_114733_create_projekt_user_pivots_table.php
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('projekt_user_pivots', function (Blueprint $table) { $table->unsignedBigInteger('user_id'); $table->unsignedBigInteger('projekt_id'); $table->primary(['user_id','projekt_id']); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('projekt_user_pivots'); } };
填充器代码
DatabaseSeeder.php
<?php namespace Database\Seeders; // use Illuminate\Database\Console\Seeds\WithoutModelEvents; use App\Models\Post; use App\Models\User; use App\Models\Projekt; use App\Models\ProjektUserPivot; use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** * Seed the application's database. * * @return void */ public function run() { User::factory(10) ->has(Post::factory()->count(10)) ->has(Projekt::factory()->count(2)) ->has(ProjektUserPivot::factory()->count(4)) ->create(); } }
PostSeeder.php
<?php namespace Database\Seeders; use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class PostSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { // } }
ProjektSeeder.php
<?php namespace Database\Seeders; use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class ProjektSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { } }
ProjektUserPivotSeeder.php
<?php namespace Database\Seeders; use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class ProjektUserPivotSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { // } }
我知道问题产生的原因,但不知道如何解决?
内容的提问来源于stack exchange,提问作者G0ngB0ng
相关产品推荐
相关产品推荐

