怎麼了夥計,我有一個關於模型的工廠和多個唯一列問題:
背景
我有一個型號命名圖片。此型號具有存儲在單獨型號中的語言支持,ImageText。 ImageText有一個image_id列,一個語言列和一個文本列。
ImageText在MySQL的的約束,該組合image_id和語言必須是唯一的。
class CreateImageTextsTable extends Migration
{
public function up()
{
Schema::create('image_texts', function ($table) {
...
$table->unique(['image_id', 'language']);
...
});
}
...
現在,我希望每個圖片播種完成後有幾個ImageText模型。這是很容易與模型的工廠,這播種機:
factory(App\Models\Image::class, 100)->create()->each(function ($image) {
$max = rand(0, 10);
for ($i = 0; $i < $max; $i++) {
$image->imageTexts()->save(factory(App\Models\ImageText::class)->create());
}
});
問題
然而,播種這種使用模式工廠和攤販時,你往往留下了這樣的信息:
[PDOException]
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '76-gn' for key 'image_texts_image_id_language_unique'
這是因爲在某些情況下,在for循環中,faker會爲圖像隨機使用同一個語言代碼兩次,從而打破['image_id','language']的唯一約束。
您可以更新ImageTextFactory這樣說:
$factory->define(App\Models\ImageText::class, function (Faker\Generator $faker) {
return [
'language' => $faker->unique()->languageCode,
'title' => $faker->word,
'text' => $faker->text,
];
});
但是,你反而得到了攤販將耗盡languageCodes已經創造出足夠的imageTexts後問題。
目前的解決方案
這是目前具有用於ImageText,其中一個爲languageCodes復位獨特的計數器和播種機調用工廠,進入for循環之前重置TE獨特的櫃檯兩個不同的工廠解決創建更多的ImageTexts。但這是代碼重複,應該有更好的方法來解決這個問題。
問題
有沒有辦法送你節省到工廠模式?如果是這樣,我可以在工廠內部進行檢查,以查看當前Image是否已經附加了任何ImageTexts,如果沒有,則重置languageCodes的唯一計數器。我的目標將是這樣的:
$factory->define(App\Models\ImageText::class, function (Faker\Generator $faker) {
$firstImageText = empty($image->imageTexts());
return [
'language' => $faker->unique($firstImageText)->languageCode,
'title' => $faker->word,
'text' => $faker->text,
];
});
這當然目前給出:
[ErrorException]
Undefined variable: image
是否有可能以某種方式實現這一目標?