Jeg løste det
Jeg søgte meget efter en løsning på dette problem og fandt ud af, at mange andre også oplevede det. Hvis du kun har brug for ét element i den anden ende af dit forhold, er det meget ligetil .
Tilføjelsen af "multi kolonne unikke begrænsning" er, hvad der gjorde dette kompliceret. Den eneste løsning, jeg fandt, var "Glem MySQL-begrænsningen og omring bare fabriksoprettelsen med en try-catch for PDO-undtagelser". Dette føltes som en dårlig løsning, da andre PDO-undtagelser også ville blive fanget, og det føltes bare ikke "rigtigt".
Løsning
For at få dette til at fungere opdelte jeg såmaskinerne til ImageTableSeeder og ImageTextTableSeeder, og de er begge meget ligetil. Deres kørselskommandoer ser begge sådan ud:
public function run()
{
factory(App\Models\ImageText::class, 100)->create();
}
Magien sker inde i ImageTextFactory:
$factory->define(App\Models\ImageText::class, function (Faker\Generator $faker) {
// Pick an image to attach to
$image = App\Models\Image::inRandomOrder()->first();
$image instanceof App\Models\Image ? $imageId = $image->id : $imageId = null;
// Generate unique imageId-languageCode combination
$imageIdAndLanguageCode = $faker->unique()->regexify("/^$imageId-[a-z]{2}");
$languageCode = explode('-', $imageIdAndLanguageCode)[1];
return [
'image_id' => $imageId,
'language' => $languageCode,
'title' => $faker->word,
'text' => $faker->text,
];
});
Dette er det:
$imageIdAndLanguageCode = $faker->unique()->regexify("/^$imageId-[a-z]{2}");
Vi bruger imageId i et regexify-udtryk og tilføjer det, der også er inkluderet i vores unikke kombination, adskilt i dette tilfælde med et '-'-tegn. Dette vil generere resultater som "841-en", "58-bz", "96-xx" osv., hvor imageId'et altid er et rigtigt billede i vores database, eller null.
Da vi klæber det unikke tag til sprogkoden sammen med imageId, ved vi, at kombinationen af image_id og languageCode vil være unik . Det er præcis, hvad vi har brug for!
Nu kan vi blot udtrække den oprettede sprogkode, eller hvilket som helst andet unikt felt, vi ønskede at generere, med:
$languageCode = explode('-', $imageIdAndLanguageCode)[1];
Denne tilgang har følgende fordele:
- Ingen grund til at fange undtagelser
- Fabrikker og såmaskiner kan adskilles for læsbarhed
- Koden er kompakt
Ulempen her er, at du kun kan generere tastekombinationer, hvor en af tasterne kan udtrykkes som regex. Så længe det er muligt, virker dette som en god tilgang til at løse dette problem.