Использование PHP Faker в Laravel для создания & quot; уникального с & quot; запись при заполнении базы данных с использованием фабрики

Так похоже на уникальное с правилом проверки (см .: https://github.com/felixkiss/uniquewith-validator), Я хочу знать, как создать запись, где один столбец является уникальным с другим. Я хочу заполнить свою базу данных следующим образом.

Пример:

В таблице «шаги» 12 шагов. Каждый шаг должен иметь 5 категорий, связанных с каждой из них, которые хранятся в таблице «step_categories». Каждой из этих категорий присваивается уникальный номер заказа от 1 до 5, который уникален для каждого «step_id».

Посмотрите это изображение здесь для примера того, как должна выглядеть база данных: https://imgur.com/a/XYA5yyn

Мне пришлось вручную вносить записи в базу данных для приведенного выше примера изображения. Я не хочу каждый раз генерировать это вручную, скажем, я сделал ошибку и должен откатывать миграции, например.

Я использую фабрику для генерации этих данных. Так фабрика зовут StepCategoriesFactory.php и ясно я звоню на завод с create() метод из DatabaseSeeder.php файл.

Я думал о том, чтобы сделать это в цикле, затем я понял, когда я позвонил 'step_id' => App\Model::all()->random()->id чтобы получить новый идентификатор, который я не смог бы гарантировать, что я не захватил идентификатор, для которого я только что сгенерировал 5 записей. Я действительно новичок в Laravel, и я не уверен, с чего начать. Там нет реальной информации о SO, где фейкер может использовать уникальное с другим столбцом. Как бы я пошел об этом?

НОТА: Идентификатор шага не всегда будет 1-12. Идентификатор шага может отличаться в зависимости от того, был ли шаг удален и переделан. Так что просто присваивая step_id равный 1-12 не будет работать.

ОБНОВИТЬ: Вот код, который я только что написал, и я думаю, что я на правильном пути. Может быть. Я схватил step_id это number поле, как это всегда будет 1-12, и я извлек IID из записи. Но теперь я застрял на том, как сгенерировать порядок 1-5, не повторяя себя. Я все еще не запустил его, поскольку он неполон, и я знаю, что он выдаст ошибку без правильного номера заказа.

ОБНОВЛЕНИЕ 2: Я думаю, что я на правильном пути здесь. Однако я получаю неопределенную ошибку переменной. Когда я помещаю первую строку из анонимной функции, она сбрасывает порядок на «1» для каждой записи. Как сделать переменную $ autoIncrement доступной для анонимной функции? Seeder остался прежним между обновлениями.

Изображение ошибки: https://imgur.com/a/ywkd0Lb
Второе изображение с ошибкой Die / Dump в терминале: https://imgur.com/a/rOGRv32

Ссылка на эту статью здесь: https://laracasts.com/discuss/channels/laravel/model-factory-increment-value-faker?page=1

ОБНОВЛЕНИЕ 3: Я забыл use ($autoIncrement) строка кода для анонимной функции. Код ниже был обновлен, но теперь я получаю другую ошибку о том, что столбец заказа имеет нулевое значение и не может быть вставлен. ясно, что это должно быть «1». Даже после того, как я позвоню $autoIncrement->next(); который должен увеличить его до ‘1’, он все равно возвращает ноль в соответствии с терминалом. Тем не менее, когда я делаю дамп на $autoIncrement->current() возвращается 1. Странно.

Ошибка обновления 3: https://imgur.com/a/STOmIjF

StepCategoriesFactory.php

use Faker\Generator as Faker;

$autoIncrement = autoIncrement();

$factory->define(App\StepCategory::class, function (Faker $faker) use ($autoIncrement) {
// Generate Created At and Updated at DATETIME
$DateTime = $faker->dateTime($max = 'now');
$autoIncrement->next();
$order = (int) $autoIncrement->current();

return [
// Generate Dummy Data
'order' =>  $order,
'name' => $faker->words(4, true),
'created_at' => $DateTime,
'updated_at' => $DateTime,
];
});

function autoIncrement()
{
for ($i = 0; $i < 5; $i++) {
yield $i;
}
}

Изменить: назначить награду за этот вопрос, так как я думаю, что для сообщества было бы полезно получить подробный ответ. Я ищу помощи, чтобы объяснить, как добиться того, чтобы я получал одну и ту же запись в каждом цикле.

4

Решение

например, если имя вашей модели Step является Steps:

$allSteps = Steps::all();
foreach($allSteps as $step){
for($i=1;$i<6;$i++){
//insert to table $step->id , $i  for example
DB::table('yourTableName')->insert([
'name'=>'Step '.$step->id.'- Category '.$i ,
'order'=>$i ,
'step_id'=>$step->id
]);
}
}
0

Другие решения

Извините, если вы не поняли мою точку зрения, поэтому я постараюсь объяснить это в коде

    use Illuminate\Database\Seeder;


$factory->define(App\StepCategory::class, function (Faker $faker) {
// Generate Created At and Updated at DATETIME
$DateTime = $faker->dateTime($max = 'now');
$step_id = function () {
return factory('App\Step')->create()->id;
};

return [
// Generate Dummy Data
'step_id' => $step_id,
'order' => uniqueOrder($step_id),
'name' => $faker->words(4, true),
'created_at' => $DateTime,
'updated_at' => $DateTime,
];
});

function uniqueOrder($step_id)
{
$unique = rand(1,5);
do {
$unique = rand(1,5);
}
while(StepCategory::where('step_id', $step_id)->andWhere( 'order', $unique)->exists())

return $unique;

}
0

НАКОНЕЦ решен!

Так что я взял в ответах каждого, и думал долго и трудно об использовании для цикла, чтобы создать номер заказа. 1-5. Проблема, с которой я столкнулся в конце, состояла в том, что переменная $ i не сбрасывалась. Поэтому после выхода я должен был проверить, равна ли переменная $ i 5, а затем сбросить ее обратно на ноль.

Вот код!

StepCategories.php

use Faker\Generator as Faker;

$autoIncrement = autoIncrement();

$factory->define(App\StepCategory::class, function (Faker $faker) use ($autoIncrement) {
// Generate Created At and Updated at DATETIME
$DateTime = $faker->dateTime($max = 'now');

// Get the next iteration of the autoIncrement Function
$autoIncrement->next();
// Assign the current $i value to a typecast variable.
$order = (int) $autoIncrement->current();


return [
// Generate Dummy Data
'order' =>  $order,
'name' => $faker->words(4, true),
'created_at' => $DateTime,
'updated_at' => $DateTime,
];
});

function autoIncrement()
{
// Start a loop
for ($i = 0; $i <= 5; $i++) {
// Yield the current value of $i
yield $i;
// If $i is equal to 5, that must mean the start of a new loop
if($i == 5) {
// Reset $i to 0 to start over.
$i = 0;
}
}
}

DatabaseSeeder.php

// Generate Dummy Categories
// Run the factory 12 times
foreach(range(1, 12) as $i) {
// Generate 5 entries each time
factory(App\StepCategory::class, 5)->create([
// Since all steps have a number 1-12 grab the step by the number column and get it's ID
'step_id' => App\Step::where('number', '=', $i)->first()->id,
]);
}

Спасибо всем, кто помог!

0
По вопросам рекламы [email protected]