Tôi đã giải quyết được nó
Tôi đã tìm kiếm rất nhiều giải pháp cho vấn đề này và thấy rằng nhiều người khác cũng trải qua nó. Nếu bạn chỉ cần một phần tử ở đầu bên kia của mối quan hệ của mình, sẽ rất dễ dàng .
Việc bổ sung "giới hạn duy nhất nhiều cột" là điều đã làm cho điều này trở nên phức tạp. Giải pháp duy nhất mà tôi tìm thấy là "Quên hạn chế MySQL và chỉ bao quanh việc tạo nhà máy với thử bắt các ngoại lệ PDO". Đây có vẻ là một giải pháp tồi vì các PDOExceptions khác cũng sẽ bị bắt và cảm thấy không "ổn".
Giải pháp
Để thực hiện công việc này, tôi đã chia các trình gieo hạt thành ImageTableSeeder và ImageTextTableSeeder, và cả hai đều rất thẳng về phía trước. Cả hai lệnh chạy của chúng đều trông giống như sau:
public function run()
{
factory(App\Models\ImageText::class, 100)->create();
}
Điều kỳ diệu xảy ra bên trong 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,
];
});
Đây là nó:
$imageIdAndLanguageCode = $faker->unique()->regexify("/^$imageId-[a-z]{2}");
Chúng tôi sử dụng imageId trong biểu thức regexify và thêm bất kỳ thứ gì cũng được đưa vào tổ hợp duy nhất của chúng tôi, được phân tách trong trường hợp này bằng ký tự '-'. Điều này sẽ tạo ra các kết quả như "841-en", "58-bz", "96-xx", v.v. trong đó imageId luôn là hình ảnh thực trong cơ sở dữ liệu của chúng tôi hoặc null.
Vì chúng tôi gắn thẻ duy nhất vào mã ngôn ngữ cùng với imageId, chúng tôi biết rằng sự kết hợp của image_id và languageCode sẽ là duy nhất . Đây chính là thứ chúng ta cần!
Giờ đây, chúng tôi có thể chỉ cần trích xuất mã ngôn ngữ đã tạo hoặc bất kỳ trường duy nhất nào khác mà chúng tôi muốn tạo, với:
$languageCode = explode('-', $imageIdAndLanguageCode)[1];
Cách tiếp cận này có những ưu điểm sau:
- Không cần nắm bắt các trường hợp ngoại lệ
- Nhà máy và Máy gieo hạt có thể được tách biệt để dễ đọc
- Mã nhỏ gọn
Điểm bất lợi ở đây là bạn chỉ có thể tạo các tổ hợp phím trong đó một trong các phím có thể được biểu thị dưới dạng regex. Miễn là có thể, đây có vẻ là một cách tiếp cận tốt để giải quyết vấn đề này.