1

I am working on application that is made up of Leads, each Lead -> hasMany -> Fields. My application will accept an infinite amount of whitelisted fields. Some Leads will have a lot of Fields, others will have maybe around 5. Due to this, I've opted for the Field table to be vertical, rather than fit in all the fields I accept horizontally, and then run into MySQL errors down the line (table too wide, etc.)

Here's my structure:

Lead Table

id
...

Field Table:

id
lead_id
field_name
field_value

I have created a model factory for my Lead model, that automatically creates 5 random fields using Faker.

I have an array of texts, numbers, dates (etc) fields which my application accepts.

Field Factory:

...

$texts = config('fields.whitelist.text');
foreach ($texts as $text) {
    $fields[$text] = $faker->sentence();
}

...

$randomField = array_random(array_keys($fields));    

return [
    'field_name' => $randomField,
    'field_value' => $fields[$randomField],
];

I've been doing this:

$lead = factory(Lead::class)->create()
         ->each(function ($l) {
             $l->fields()->save(factory(Field::class, 5)->make());
         });

However, I now have a minimum array of Fields which each Lead must have. I have these minimum fields in another config.

Is it possible to automatically create the x minimum Fields on the vertical table, using a factory?

E.g.

Minimum Fields

first_name
date_of_birth

How can I write a factory to automatically create the following structure:

[
    'field_name' => 'first_name',
    'field_value' => '<random name>',
],
[
    'field_name' => 'date_of_birth',
    'field_value' => '<random date>',
],

Edit: and if possible, not insert duplicate field_name values. Not like it's 100% deal breaker, but I want to make sure I 100% know what data I am working with, so checking x number of duplicates I imagine would be a nightmare

4

1 回答 1

2

If you want each Lead to have those minimum fields, then add those fields to your each() closure. Like this:

$lead = factory(Lead::class)->create()->each(function ($lead) {
    $lead->fields()->createMany([
        'field_name' => 'first_name',
        'field_value' => $faker->firstName,
    ],
    [
        'field_name' => 'date_of_birth',
        'field_value' => $faker->dateTime(),
    ]);
    $lead->fields()->save(factory(Field::class, 3)->make());
});

I changed the Field factory to 3 because there are 2 fields from the "minimum fields" that are inserted for every Lead.

于 2018-03-12T18:56:06.680 回答