Home > database >  How to get related Model id in Laravel factory
How to get related Model id in Laravel factory

Time:10-07

I am trying to save the image using faker in the storage folder. I want to keep the images inside the property ID folder. I have tried the below code but it is not working. It hangs the command prompt. The properties have multiple images and are a one-to-many relation. The code below is for the PropertyImageFactory class.

public function definition()
    {
        $property_id = $this->create(Property::class)->id;

        return [
            'name' => $this->faker->image(storage_path('app/property-images/'.$property_id), 200, 200, 'cats'),
            'sort_order' => $this->faker->numberBetween(1, 10),
            'created_at' => now(),
            'updated_at' => now(),
        ];
    }

Laravel documentation has 'user_id' => User::factory(), I can't use this because it returns an object and I can't concatenate to string.

CodePudding user response:

Laravel documentation has 'user_id' => User::factory(), I can't use this because it returns an object and I can't concatenate to string.

Yup, that will return a UserFactory object just as Property::factory() will return a PropertyFactory. What you want to do is call the create() method on the factory and get the id from the record that is created.

$proprty_id = (\App\Models\Property::factory()->create())->id;

CodePudding user response:

Laravel extracts the ID from the SomeModel::factory(), that's all the magic of Laravel. To do this, you need to properly describe the SomeModelFatory. You can use: $property_id = Property::factory();

As far as I know faker->image no longer works, I can advise using an auxiliary class for image formation.

<?php

namespace App\Helpers;

use Faker\Factory;
use Illuminate\Support\Facades\File;

class Image
{
    public static function imageUrl(
        int $width = 640,
        int $height = 480,
        bool $randomizeColors = false,
        bool $randomizeTxt = false,
        string $format = 'jpg'
    ): string
    {
        $baseUrl = "https://dummyimage.com";
        $size = "/{$width}x{$height}";
        $colors = "/aaa/fff";
        $format = '.' . preg_replace('~^\b(?:jpg|png|gif)$~', 'jpg', $format);

        if ($randomizeColors) {
            $backgroundColor = str_replace('#', '', Factory::create()->safeHexColor);
            $foreColor = str_replace('#', '', Factory::create()->safeHexColor);
            $colors = "/{$backgroundColor}/{$foreColor}";
        }

        return $baseUrl . $size . $colors . $format . ($randomizeTxt ? '&text=' . Factory::create()->word : '');
    }

    public static function fake(
        string $dir = null,
        int $width = 640,
        int $height = 480,
        bool $randomizeColors = false,
        bool $randomizeTxt = false,
        string $format = 'jpg',
        bool $fullPath = false
)
    {
        $dir = is_null($dir) ? sys_get_temp_dir() : $dir;

        if (!is_dir($dir) || !is_writable($dir)) {
            throw new \InvalidArgumentException("Unable to write to directory $dir");
        }

        $name = md5(uniqid(empty($_SERVER['SERVER_ADDR']) ? '' : $_SERVER['SERVER_ADDR'], true));
        $filename = $name . ".$format";
        $filepath = $dir . DIRECTORY_SEPARATOR . $filename;

        $url = static::imageUrl($width, $height, $randomizeColors, $randomizeTxt, $format);

        try {
            $image = file_get_contents($url, false, stream_context_create(['http' => ['timeout' => 10]]));

            try {
                if (!File::put($filepath, $image)) {
                    return false;
                }
            } catch (\Exception $e) {
                throw new \Exception($e->getMessage());
            }
        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
        }

        return $fullPath ? $filepath : $filename;
    }
}

and use:

public function definition()
{
    $property_id = Property::factory();
    $dir = storage_path('app' . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . $property_id);
    mkdir($dir, 755);

    return [
        'name' => (\App\Helpers\Image())->fake($dir, 200, 200),
        'sort_order' => $this->faker->numberBetween(1, 10)
        ];
    }
  • Related