如何在Laravel中使用伪造者为随机ID或null播种?

时间:2018-08-10 11:13:22

标签: laravel laravel-5 seeding faker

我正在尝试为具有相同表的随机ID的parent_id列设置种子,或者将其设置为null。

我认为这会起作用:

...
'parent_id' => $faker->boolean() ? Page::all()->random()->id : null,
...

但是我收到以下错误消息:

  You requested 1 items, but there are only 0 items available. 

有人知道该怎么做吗?

Update1:​​

使用伪动漫答案,我尝试了以下方法:

$factory->define(Page::class, function (Faker\Generator $faker) {
...
    $parent_id = null;
...
    $has_parent = $faker->boolean(50);
    Log::debug('$has_parent' . $has_parent);
    if ($has_parent) {
        $parents = Page::all();
        Log::debug('$parents' . count($parents));

        if ($parents->isEmpty()) {
            Log::debug('isEmpty');

            $parent_id = null;
        } else {
            Log::debug('$parents->random()' . print_r($parents->random(), true));
            $parent_id = $parents->random()->id;
        }
    }

    return [
...

        'parent_id' => $parent_id,
...
    ];
}

根据我每次运行Page::all();所看到的,返回空。 知道为什么吗?

5 个答案:

答案 0 :(得分:2)

尝试一下:

'parent_id' => $faker->boolean(50) ? Page::orderByRaw('RAND()')->first()->id : null,

基本上,我们是说随机订购,先获取,然后获取其ID。

boolean(50)应该为您提供50%的真实机会,因此50%的机会为虚假。

答案 1 :(得分:2)

$factory->define(Page::class, function (Faker\Generator $faker) {
    $ids = Page::pluck('id')->toArray();

    return [
        'parent_id' = empty($ids) ? null : $faker->optional(0.9, null)->randomElement($ids);  // 10% chance of null
    ];
});

答案 2 :(得分:0)

发生错误是因为您对页面(page:all()-> random())的查询未返回任何结果。

基本上,您的问题是,您甚至在创建页面之前就尝试创建页面的父级。

您可以尝试检查Page :: all()是否返回非空集合,如果是,则从那里获取一个随机元素,否则请创建一个新元素。

我个人会做一些事情,例如为null父元素创建一个类,并为null和非空父元素创建一个类。

$factory->defineAs(Page::class, 'ParentPage', function (Faker $faker) {
    return [
        //the rest of your elements here
        'parent_id' => null
    ];
});

$factory->defineAs(Page::class, 'page', function (Faker $faker) {
    $has_parent = $faker->boolean();
    if($has_parent) {
        $parents = Page::all();
        if($parents->isEmpty()) {
            $parent_id = factory(Page::class, 'ParentPage')->create()->id;
        } else {
            $parent_id = $parents->random()->id;
        }
    }
    return [
        //the rest of your elements here
        'parent_id' => $has_parent? $parent_id : null
    ];
});

您可以在播种器中创建常规页面,例如factory(Page::class, 'page')->times(50)->create();

以上代码未经测试,但逻辑应正确。

答案 3 :(得分:0)

<ContentPage
    x:Class="Sample.MainPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:Sample">
    <ContentPage.Content>
        <StackLayout>
            <local:MyEntry />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

答案 4 :(得分:0)

以“父”作为父模型,我这样做:

  1. 首先为父级播种;
  2. 在工厂中使用以下代码播种子表:

'parent_id' => $faker->optional()->randomElement(App\Parent::all()->pluck('id'))

它之所以有效,是因为造假者的 randomElement()接受一个数组,您在其中填充了父表的所有且仅包含'id'值。

optional()伪造者的修饰符会在 parent_id 中随机放置或不放置NULL。如faker's GitHub中所述, optional()有时会绕过提供程序以返回默认值(默认为NULL) 。 您还可以指定接收默认值和返回默认值的可能性。

注意:如果没有为Parent表设置种子,您将无法执行任何操作。如果是这样,请考虑dlnsk的答案。