I have a similar solution in one of my projects where I create a single genres table.
public function up(): void
{
Schema::create('genres', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->foreignIdFor(MediaType::class);
$table->timestamps();
});
}
That I then use for books, movies, games, and records. The foreign id is the type of the media associated with the genre.
public function up(): void
{
Schema::create('media_types', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
I then use a database view for each of the above mentioned types, and it only returns the genres for the specific media type.
public function up(): void
{
DB::statement("CREATE OR REPLACE VIEW record_genre_views AS
SELECT g.name
FROM genres g,
media_types mt
WHERE g.media_type_id = mt.id
AND mt.name = 'record';
");
}