Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating Fake Data with the Factory #364

Closed
Dezmonter opened this issue Aug 28, 2023 · 6 comments
Closed

Creating Fake Data with the Factory #364

Dezmonter opened this issue Aug 28, 2023 · 6 comments

Comments

@Dezmonter
Copy link

Please tell me how can I create a factory with Product (id) and ProductDescription (product_id, name) models using your wonderful package.
Is there a macro in the package for this?

@PavelZanek
Copy link

Would this guide at PavelZanek.com be of any help to you?

@Dezmonter
Copy link
Author

Dezmonter commented Sep 1, 2023

Yes, I tried it, but unfortunately I get an error and I don’t know what to do ((

 `  TypeError

  Illuminate\Database\Grammar::parameterize(): Argument #1 ($values) must be of type array, int given, called in E:\OSPanel\domains\lik\vendor\laravel\framework\src\Illuminate\Database\Query\Grammars\Grammar.php on line 1047

  at vendor\laravel\framework\src\Illuminate\Database\Grammar.php:175
    171▕      *
    172▕      * @param  array  $values
    173▕      * @return string
    174▕      */
  ➜ 175▕     public function parameterize(array $values)
    176▕     {
    177▕         return implode(', ', array_map([$this, 'parameter'], $values));
    178▕     }
    179▕

  1   vendor\laravel\framework\src\Illuminate\Database\Query\Grammars\Grammar.php:1047
      Illuminate\Database\Grammar::parameterize()

  2   [internal]:0
      Illuminate\Database\Query\Grammars\Grammar::Illuminate\Database\Query\Grammars\{closure}()`

@PavelZanek
Copy link

Can you please share what your models (Product and ProductDescription) and the ProductFactory look like?

@Dezmonter
Copy link
Author

Dezmonter commented Sep 6, 2023

Yes, of course, my model Doctor

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use App\Models\Scopes\CityScope;
use App\Services\TranslatableService;

class Doctor extends Model
{
    use HasFactory, TranslatableService;

    public $sortables = ['id', 'start_year'];

    protected $fillable = [
        'city_id',
        'degree',
        'qualification',
        'start_year',
        'viewed',
        'status',
        'image',
        'sort_order',
    ];

    public $translatedAttributes = [
        'slug',
        'name',
        'description',
        'education',
        'meta_title',
        'meta_description',
        'meta_keywords',
    ];
}

My model DoctorTranslation

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class DoctorTranslation extends Model
{
    use HasFactory;

    public $timestamps = false;

    protected $fillable = [
        'slug',
        'name',
        'description',
        'education',
        'meta_title',
        'meta_description',
        'meta_keywords',
    ];
}

And finally my factory DoctorFactory

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;
use App\Models\City;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Doctor>
 */
class DoctorFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        $locales = ['uk', 'ru'];

        $translations = collect($locales)->mapWithKeys(function($locale) {
            return [
                $locale => [
                    'slug' => fake()->unique()->randomNumber(4) . '-' . fake()->slug(3),
                    'name' => fake()->unique()->name(),
                    'description' => fake()->text(),
                    'education' => fake()->text(),
                ]
            ];
        })->toArray();

        return array_merge([
            'city_id' => City::get()->random()->id,
            'degree' => fake()->numberBetween(1, 2),
            'qualification' => fake()->numberBetween(1, 3),
            'start_year' => fake()->year(),
            'viewed' => fake()->numberBetween(50, 5500),
            'status' => true,
            'image' => fake()->imageUrl(250, 250),
            'sort_order' => fake()->numberBetween(0, 10),
            'created_at' => fake()->dateTimeBetween('-4 week', '-3 week'),
            'updated_at' => fake()->dateTimeBetween('-2 week', '-1 week'),
        ], $translations);
    }
}

@PavelZanek
Copy link

PavelZanek commented Sep 7, 2023

If I use the below solution everything works for me. First, I created probably similar migrations to yours.

translatable.php:

    ...
    'locales' => [
        'uk',
        'ru',
    ],
    ...

City Table:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('cities', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('cities');
    }
};

Doctor Table:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('doctors', function (Blueprint $table) {
            $table->id();
            $table->foreignId('city_id')->constrained();
            $table->integer('degree');
            $table->integer('qualification');
            $table->integer('start_year');
            $table->integer('viewed');
            $table->boolean('status')->default(false);
            $table->string('image');
            $table->integer('sort_order');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('doctors');
    }
};

DoctorTranslation Table:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('doctor_translations', function (Blueprint $table) {
            $table->id();

            $table->foreignId('doctor_id')->constrained();
            $table->string('locale')->index();

            $table->string('slug');
            $table->string('name');
            $table->text('description');
            $table->text('education');

            $table->unique(['doctor_id', 'locale']);
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('doctor_translations');
    }
};

City model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class City extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
    ];
}

Doctor model:

<?php

namespace App\Models;

use Astrotomic\Translatable\Contracts\Translatable as TranslatableContract;
use Astrotomic\Translatable\Translatable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Doctor extends Model implements TranslatableContract
{
    use HasFactory, Translatable;

    protected $fillable = [
        'city_id',
        'degree',
        'qualification',
        'start_year',
        'viewed',
        'status',
        'image',
        'sort_order',
    ];

    public $translatedAttributes = [
        'slug',
        'name',
        'description',
        'education',
        'meta_title',
        'meta_description',
        'meta_keywords',
    ];
}

DoctorTranslation model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class DoctorTranslation extends Model
{
    use HasFactory;

    public $timestamps = false;

    protected $fillable = [
        'slug',
        'name',
        'description',
        'education',
        'meta_title',
        'meta_description',
        'meta_keywords',
    ];
}

CityFactory:

<?php

namespace Database\Factories;

use App\Models\City;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\City>
 */
class CityFactory extends Factory
{
    protected $model = City::class;

    public function definition(): array
    {
        return [
            'name' => fake()->city(),
        ];
    }
}

DoctorFactory:

<?php

namespace Database\Factories;

use App\Models\City;
use App\Models\Doctor;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Doctor>
 */
class DoctorFactory extends Factory
{
    protected $model = Doctor::class;

    public function definition(): array
    {
        $locales = ['uk', 'ru'];

        $translations = collect($locales)->mapWithKeys(function($locale) {
            return [
                $locale => [
                    'slug' => fake()->unique()->randomNumber(4) . '-' . fake($locale)->slug(3),
                    'name' => fake($locale)->unique()->name(),
                    'description' => fake($locale)->text(),
                    'education' => fake($locale)->text(),
                ]
            ];
        })->toArray();

        return array_merge([
            'city_id' => City::factory(),
            'degree' => fake()->numberBetween(1, 2),
            'qualification' => fake()->numberBetween(1, 3),
            'start_year' => fake()->year(),
            'viewed' => fake()->numberBetween(50, 5500),
            'status' => fake()->boolean(),
            'image' => fake()->imageUrl(250, 250),
            'sort_order' => fake()->numberBetween(0, 10),
            'created_at' => fake()->dateTimeBetween('-4 week', '-3 week'),
            'updated_at' => fake()->dateTimeBetween('-2 week', '-1 week'),
        ], $translations);
    }
}

Seeder:

<?php

namespace Database\Seeders;

use App\Models\Doctor;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        Doctor::factory()->count(10)->create();
    }
}

@github-actions
Copy link
Contributor

This issue is stale because it has been open 21 days with no activity. Remove stale label or comment or this will be closed in 7 days

@github-actions github-actions bot added the stale label Sep 30, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Oct 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants