Laravel seeds и factories для связанных таблиц

243
30 октября 2018, 15:40

Пытаюсь освоиться с seeds, factories и использование Faker в Laravel 5.6. Пытаюсь заполнять фейковыми данными связанные таблицы.

Связь один ко многим

app\Product.php

class Product extends Model
{
    public function category()
    {
        return $this->belongsTo('App\Category');
    }
}

app\Category.php

class Category extends Model
{
    public function products()
    {
        return $this->hasMany('App\Product');
    }
}

Сначала я описываю factories

databasse\factories\CategoriesFactory.php

use Faker\Generator as Faker;
$factory->define(App\Category::class, function (Faker $faker) {
    return [
        'name' => $faker->sentence($nbWords = rand(2, 3), $variableNbWords = true),
        'slug' => $faker->slug(3)
    ];
});

database\factories\ProductsFactory.php

use Faker\Generator as Faker;
$factory->define(App\Product::class, function (Faker $faker) {
    return [
        'category_id' => rand(1, 10), //Использую rand между 1 и 10, т.к буду создавать 10 категорий в seeds
        'name' => $faker->text(45),
        ...
    ];
});

В seeds я описываю вызов каждой фабрики. И регистрирую каждый seed в DatabaseSeeder.php

database\seeds\CategoriesTableSeeds.php

use Illuminate\Database\Seeder;
class CategoriesTableSeeder extends Seeder
{
    public function run()
    {
        factory(\App\Category::class, 10)->create();
    }
}

database\seeds\ProductsTableSeeds.php

use Illuminate\Database\Seeder;
class ProductsTableSeeder extends Seeder
{
    public function run()
    {
        factory(\App\Product::class, 1000)->create();
    }
}

database\seeds\DatabaseSeeder.php

use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
    public function run()
    {
         $this->call(CategoriesTableSeeder::class);
         $this->call(ProductsTableSeeder::class);
    }
}

Т.к. в CategoriesTableSeeds.php создаю 10 категорий, то в database\factories\ProductsFactory.php для поля category_id я вызываю rand(1, 10). Но мне этот способ кажется не оптимальным. Можно ли как-то автоматизировать и этот процесс? Оптимальным не кажется мне ещё и потому, что хоть для связи один ко многим это ещё можно применить, а вот для связи многие ко многим - едва ли.

Связь многие ко многим

Помимо всего прочего продуктам можно назначать метки

app\Product.php

class Product extends Model
{
    public function labels()
    {
        return $this->belongsToMany('App\Label');
    }
}

app\Label.php

class Label extends Model
{
    public function products()
    {
        return $this->belongsToMany('App\Product');
    }
}

Я сделал фабрику для создания меток.

database\factories\LabelsFactory.php

use Faker\Generator as Faker;
$factory->define(App\Label::class, function (Faker $faker) {
    return [
        'name' => $faker->sentence($nbWords = rand(1, 3), $variableNbWords = true),
    ];
});

Что делать дальше я не знаю. Фабрику или сидера описать для связи многие ко многие не представляю как, потому что как минимум нужно будет создать модель этой таблицы label_product. А зачем модель, если связи и без того описаны? В общем это второй вопрос, который возник при разборе темы.

Как быть?

Answer 1

Вам нужно сгенерировать фековые данные для ваших связей в бд? Вот пример для "многие ко многим":

// Создать 5 Foo's и Bar для кажлого
factory(App\Foo::class, 5)->create()->each(function($foo) {
    $foo->bars()->save(factory(App\Bar::class)->make());
});

Если надо изменять pivot, то можете попробовать:

// Создать 5 Foo's и Bar для кажлого
factory(App\Foo::class, 5)->create()->each(function($foo) {
    $bar = factory(App\Bar::class)->make()
    $foo->bars()->save($bar);
    $bar->pivot->price = 12; 
    $bar->pivot->save();
});
READ ALSO
Предотвратить повторную отправку формы

Предотвратить повторную отправку формы

КАК предотвратить повторную отправку формы

160
Как поменять содержимое ComboBox в Битрикс?

Как поменять содержимое ComboBox в Битрикс?

Имеется раздел CRM, в нём КомпанииПри добавлении новой компании предлагается выбрать из выпадающего списка Тип

152
Не отрабатывает comment-reply.js wordpress

Не отрабатывает comment-reply.js wordpress

Создан вывод комментариев при помощи дефолтной функции wp_list_comments()

164
Помощь по коду для WordPress

Помощь по коду для WordPress

Такая ситуация:

161