Basile404's avatar

Factories with array data as a value in Laravel 11

Hey

I am trying to make a factory of a list of projects (model: Project) so I can seed during the migration of my DB.

One of the fields is a "gallery" field with a list of images in it for each project. I am trying to set an array as a default value with a dummy image to work with.

The issue

It seems like I can't upload a list/array as a default value for this factory key=>value pair.

I am getting an "array to string conversion error".

My Code

This is my factory (ProjectFactory.php)

class ProjectFactory extends Factory
{
	. . .
    public function definition(): array
    {
        return [
            "title" => "Project One",
            "slug" => "project-one",
            "cover" => "images/templates/dummy.png",
            "gallery" =>["images/templates/dummy.png","images/templates/dummy.png","images/templates/dummy.png"],
            "description" => fake()->text(),
            "language" => "en",
            "title" => "Project One"
        ];
    }
}

In my migration, the "gallery" column is to be setup as a json format.

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('projects', function (Blueprint $table) {
            $table->id();
            $table->string("title")->unique();
            $table->string('slug');
            $table->longText("description");
            $table->string("language");
            $table->string('cover');
            $table->json('gallery')->nullable();
            $table->timestamps();
        });
    }
	. . .
};

Did I miss something? Thanks!

0 likes
1 reply
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

It looks like you're on the right track with your factory and migration setup. However, when working with JSON columns in Laravel, you need to ensure that the array data you're assigning to the JSON column is actually being cast to JSON when it's being inserted into the database.

In your Project model, you should specify that the gallery attribute should be cast to array or json. This will automatically serialize the array to JSON when saving to the database and deserialize it back to an array when you access it from the model.

Here's how you can define the $casts property in your Project model:

class Project extends Model
{
    // ...

    protected $casts = [
        'gallery' => 'array',
    ];

    // ...
}

With this cast in place, Laravel will handle the serialization and deserialization of the gallery field automatically.

Additionally, ensure that your factory definition is returning a serialized JSON string for the gallery field if your database expects a JSON string. However, with the $casts property set in your model, this shouldn't be necessary as Laravel will handle the serialization for you.

Here's your factory code, which should work as expected with the $casts property set in your model:

class ProjectFactory extends Factory
{
    // ...
    public function definition(): array
    {
        return [
            "title" => "Project One",
            "slug" => "project-one",
            "cover" => "images/templates/dummy.png",
            "gallery" => ["images/templates/dummy.png", "images/templates/dummy.png", "images/templates/dummy.png"],
            "description" => fake()->text(),
            "language" => "en",
        ];
    }
}

Make sure you have the Project model use the HasFactory trait so that you can use the factory methods on the model:

use Illuminate\Database\Eloquent\Factories\HasFactory;

class Project extends Model
{
    use HasFactory;

    // ...
}

Now, when you run your database seeder, it should correctly insert the gallery field as a JSON-encoded string into your database without any array to string conversion errors.

1 like

Please or to participate in this conversation.