<commit_before># Eloquent Populator

This is a package to populate Laravel's Eloquent ORM's models by guessing the best [Faker](https://github.com/fzaninotto/Faker) formatters for their attributes from their columns' names and types. It is based on Faker's other ORMs' adapters, but was released as a stand-alone package because several functionalities were added.

# Table of contents

- [Installation](#installation)
- [Seeding](#seeding)
- [Relationships](#relationships)
    - [Belongs To](#belongs-to)
    - [Morph To](#morph-to)
    - [Belongs To Many](#belongs-to-many)
- [Model Factory integration](#model-factory-integration)
- [Testing](#testing)
- [Laravel-Translatable integration](#laravel-translatable-integration)

## Installation

Require this package with Composer

```bash
$ composer require --dev guidocella/eloquent-populator ^2
```

Or manually add it to the development dependencies in your `composer.json` and run `composer update`. You may want to substitute it for Faker, since it will be required by Populator.

```json
"guidocella/eloquent-populator": "^2"
```

## Seeding

Either type hint `EloquentPopulator\Populator` in your `DatabaseSeeder`'s `run` method to have it dependency injected if you're using Laravel 5.4+

```php
public function run(EloquentPopulator\Populator $populator)
{
```

or call the `populator` helper with no arguments to get a Populator instance.

```php
$populator = populator();
```

### Adding models

Now for each model you want to create, call `add` passing the class and the number of instances to generate. Let's add 10 users and 5 posts.

```php
$populator->add(User::class, 10)
          ->add(Post::class, 5);
```

Populator will try to guess the best Faker formatter to use for each column based on its name. For example, if a column is called `first_name`, it will use `$faker->firstName`. If unable to guess by the column's name, it will guess the formatter by the column's type. For example, it will use `$faker->text` for a `VARCHAR` column, or a Carbon instance for a `TIMESTAMP`.

To customize the values of certain columns, pass them as the 3rd argument. If they're Faker formatters, you'll have to wrap them in a closure to get different values for each row.

```php
$populator->add(Post::class, 5, [
    'content'   => function () use ($faker) {
        return $faker->paragraph;
    }
]);
```

Any closure passed will receive the model instance and the previously inserted primary keys.

```php
$populator->add(Post::class, 5, [
    'user_id'   => function ($post, $insertedPKs) use ($faker) {
        return $faker->randomElement($insertedPKs[User::class]);
    },
    'user_type' => function ($post) {
        return $post->user->type;
    },
]);
```

The model received by the closures will have non-closure attributes and closure attributes of columns that come before in the database already set.
 
You can also pass an array of functions as the 4th argument and they'll be called before the model's insertion.

```php
$populator->add(Post::class, 5, [], [
    function ($post, $insertedPKs) {
        $post->doSomethingBeforeSaving();
    },
]);
```

If only the class name is passed, the number of models to populate defaults to 1.

### Creating the models

Finally, call `seed` to populate the database with the added models.
 
 ```php
$populator->add(User::class, 10)
           ->add(Post::class, 5)
           ->seed();
 ```

If a column that wasn't overridden is nullable, each value inserted by `seed` will have a 50% of being set to null or to the guessed formatter.

`seed` returns the inserted primary keys and runs one insert per 500 rows of every model to speed up the seeding (the chunking in blocks of 500 rows is because SQL limits how many rows you can insert at once).

Even though it bulk inserts the models, timestamps are still populated with random datetimes since their formatters are guessed along those of the other columns, and even mutators and JSON casts will work (internally Populator fills a model and gets its attributes every time to bulk insert them later), however Eloquent events won't fire.

### execute()

If you want the events to be dispatched, you can use `execute()` as an alternative to `seed()`. It creates the added models one by one, and returns all the created models or collections, depending on whether their quantity was 1 or greater, indexed by model class name.

```php
$createdModels = $populator->add(User::class, 10)
                           ->add(Post::class, 5)
                           ->execute();

$userModel = $createdModels[User::class];
$postCollection = $createdModels[Post::class];
```

`execute()` doesn't make nullable columns optional, since it is more likely to be used for testing than for seeding, and when testing creating models with predictable values can be more useful.

## Relationships

If a model shares a relationship with another one that was previously added, Populator will associate them.

### Belongs To

If a model belongs to another one that was added before it, Populator will associate the child model to a random one of its potential owners.
<commit_msg>Fix readme<commit_after># Eloquent Populator

This is a package to populate Laravel's Eloquent ORM's models by guessing the best [Faker](https://github.com/fzaninotto/Faker) formatters for their attributes from their columns' names and types. It is based on Faker's other ORMs' adapters, but was released as a stand-alone package because several functionalities were added.

# Table of contents

- [Installation](#installation)
- [Seeding](#seeding)
- [Relationships](#relationships)
    - [Belongs To](#belongs-to)
    - [Morph To](#morph-to)
    - [Belongs To Many](#belongs-to-many)
- [Model Factory integration](#model-factory-integration)
- [Testing](#testing)
- [Laravel-Translatable integration](#laravel-translatable-integration)

## Installation

Require this package with Composer

```bash
$ composer require --dev guidocella/eloquent-populator ^2
```

Or manually add it to the development dependencies in your `composer.json` and run `composer update`. You may want to substitute it for Faker, since it will be required by Populator.

```json
"guidocella/eloquent-populator": "^2"
```

## Seeding

Either type hint `EloquentPopulator\Populator` in your `DatabaseSeeder`'s `run` method to have it dependency injected if you're using Laravel 5.4+

```php
public function run(EloquentPopulator\Populator $populator)
{
```

or call the `populator` helper with no arguments to get a Populator instance.

```php
$populator = populator();
```

### Adding models

Now for each model you want to create, call `add` passing the class and the number of instances to generate. Let's add 10 users and 5 posts.

```php
$populator->add(User::class, 10)
          ->add(Post::class, 5);
```

Populator will try to guess the best Faker formatter to use for each column based on its name. For example, if a column is called `first_name`, it will use `$faker->firstName`. If unable to guess by the column's name, it will guess the formatter by the column's type. For example, it will use `$faker->text` for a `VARCHAR` column, or a Carbon instance for a `TIMESTAMP`.

To customize the values of certain columns, pass them as the 3rd argument. If they're Faker formatters, you'll have to wrap them in a closure to get different values for each row.

```php
$populator->add(Post::class, 5, [
    'content'   => function () use ($faker) {
        return $faker->paragraph;
    }
]);
```

Any closure passed will receive the model instance and the previously inserted primary keys.

```php
$populator->add(Post::class, 5, [
    'user_id'   => function ($post, $insertedPKs) use ($faker) {
        return $faker->randomElement($insertedPKs[User::class]);
    },
    'user_type' => function ($post) {
        return $post->user->type;
    },
]);
```

The model received by the closures will have non-closure attributes and closure attributes of columns that come before in the database already set.
 
You can also pass an array of functions as the 4th argument and they'll be called before the model's insertion.

```php
$populator->add(Post::class, 5, [], [
    function ($post, $insertedPKs) {
        $post->doSomethingBeforeSaving();
    },
]);
```

If only the class name is passed, the number of models to populate defaults to 1.

### Creating the models

Finally, call `seed` to populate the database with the added models.
 
 ```php
$populator->add(User::class, 10)
           ->add(Post::class, 5)
           ->seed();
 ```

If a column that wasn't overridden is nullable, each value inserted by `seed` will have a 50% of being set to null or to the guessed formatter.

`seed` returns the inserted primary keys and runs one insert per 500 rows of every model to speed up the seeding (the chunking in blocks of 500 rows is because SQL limits how many rows you can insert at once).

Even though it bulk inserts the models, timestamps are still populated with random datetimes since their formatters are guessed along those of the other columns, and even mutators and JSON casts will work (internally Populator fills a model and gets its attributes every time to bulk insert them later), however Eloquent events won't fire.

### execute()

If you want the events to be dispatched, you can use `execute()` as an alternative to `seed()`. It creates the added models one by one, and returns all the created models or collections, depending on whether their quantity was 1 or greater, indexed by model class name.

```php
$createdModels = $populator->add(User::class)
                           ->add(Post::class, 5)
                           ->execute();

$userModel = $createdModels[User::class];
$postCollection = $createdModels[Post::class];
```

`execute()` doesn't make nullable columns optional, since it is more likely to be used for testing than for seeding, and when testing creating models with predictable values can be more useful.

## Relationships

If a model shares a relationship with another one that was previously added, Populator will associate them.

### Belongs To

If a model belongs to another one that was added before it, Populator will associate the child model to a random one of its potential owners.

{'fraction_non_alphanumeric': 0.0959117962728071, 'fraction_numerical': 0.005854229680944482, 'mean_word_length': 4.09190263288624, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 45, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5720465', 'n_tokens_mistral': 2973, 'n_tokens_neox': 2758, 'n_words': 1330}