Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Michael Fayez's avatar

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`u754910178_laravel`.`designs`, CONSTRAINT `post_fk_9058591` FOREIGN KEY (`post_id`) REFERENCE

I would like to save design in the database but I got this error on my server here is my livewire design component :-

<?php

namespace App\Http\Livewire\Design;

use App\Models\Design;
use App\Models\Post;
use App\Models\Project;
use App\Models\Team;
use Livewire\Component;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
use App\Listeners\Design\DesignCreatedEmail;
use App\Events\Design\DesignCreated;


class Create extends Component
{
    public Design $design;

    public $posts;
    public $projects;
    public $post;
    public $post_id;
    public $project;

    public array $mediaToRemove = [];

    public array $listsForFields = [];

    public array $mediaCollections = [];

    public $selectedProjectId = null;

    public function addMedia($media): void
    {
        $this->mediaCollections[$media['collection_name']][] = $media;
    }

    public function removeMedia($media): void
    {
        $collection = collect($this->mediaCollections[$media['collection_name']]);

        $this->mediaCollections[$media['collection_name']] = $collection->reject(fn ($item) => $item['uuid'] === $media['uuid'])->toArray();

        $this->mediaToRemove[] = $media['uuid'];
    }

    protected function syncMedia(): void
    {
        collect($this->mediaCollections)->flatten(1)
            ->each(fn ($item) => Media::where('uuid', $item['uuid'])
                ->update(['model_id' => $this->design->id]));

        Media::whereIn('uuid', $this->mediaToRemove)->delete();
    }

    public function mount(Design $design)
    {
        $this->design = $design;
        $this->projects = Project::all(); // Load all projects
        $this->posts = collect();
        $this->initListsForFields();
    }

    public function updatedSelectedProjectId($projectId)
    {
        $this->posts = Post::where('project_id', $projectId)->get();
    }



    public function render()
    {
        return view('livewire.design.create');
    }


    public function submit()
{
    $this->validate();

    // Assign the selected project and post IDs to the design instance
    $this->design->project_id = $this->selectedProjectId;
    $this->design->post_id = $this->selectedProjectId;
    $this->design->save();
    $this->syncMedia();
    event(new DesignCreated($this->design));

    return redirect()->route('admin.designs.index');
}




    protected function rules(): array
    {
        return [
            'design.project_id' => [
                'integer',
                'exists:projects,id',
                'nullable',
            ],
            'design.post_id' => [
                'integer',
                'exists:posts,id',
                'nullable',
            ],
            'mediaCollections.design_design' => [
                'array',
                'required',
            ],
            'mediaCollections.design_design.*.id' => [
                'integer',
                'exists:media,id',
            ],
            'design.statues' => [
                'nullable',
                'in:' . implode(',', array_keys($this->listsForFields['statues'])),
            ],
            'design.confirmation' => [
                'nullable',
                'in:' . implode(',', array_keys($this->listsForFields['confirmation'])),
            ],
            'design.note' => [
                'string',
                'nullable',
            ],
            'design.review' => [
                'nullable',
                'in:' . implode(',', array_keys($this->listsForFields['review'])),
            ],
            'design.team_id' => [
                'integer',
                'exists:teams,id',
                'required',
            ],
        ];
    }

    protected function initListsForFields(): void
    {
        $this->listsForFields['project']      = Project::pluck('name', 'id')->toArray();
        $this->listsForFields['post']         = Post::pluck('title', 'id')->toArray();
        $this->listsForFields['statues']      = $this->design::STATUES_RADIO;
        $this->listsForFields['confirmation'] = $this->design::CONFIRMATION_RADIO;
        $this->listsForFields['review']       = $this->design::REVIEW_RADIO;
        $this->listsForFields['team']         = Team::pluck('name', 'id')->toArray();
    }
}

Here is my design Model

<?php

namespace App\Models;

use App\Support\HasAdvancedFilter;
use App\Traits\Auditable;
use App\Traits\Tenantable;
use Carbon\Carbon;
use DateTimeInterface;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;

class Design extends Model implements HasMedia
{
    use HasFactory, HasAdvancedFilter, SoftDeletes, Tenantable, InteractsWithMedia, Auditable;

    public $table = 'designs';

    protected $appends = [
        'design',
    ];

    protected $dates = [
        'created_at',
        'updated_at',
        'deleted_at',
    ];

    public const CONFIRMATION_RADIO = [
        'confirmed' => 'Confirmed',
        'try again' => 'Try again',
        'edit'      => 'Edit',
    ];

    public const STATUES_RADIO = [
        'in progress' => 'In Progress',
        'published'   => 'Published',
        'scheduled'   => 'Scheduled',
    ];

    protected $fillable = [
        'project_id',
        'post_id',
        'statues',
        'confirmation',
        'note',
        'review',
        'team_id',
    ];

    public const REVIEW_RADIO = [
        'not bad'   => 'Not Good',
        'good'      => 'Good',
        'very good' => 'Very Good',
        'excellent' => 'Excellent',
        'brillent'  => 'Brillent',
    ];

    public $orderable = [
        'id',
        'project.name',
        'post.title',
        'created_at',
        'statues',
        'confirmation',
        'note',
        'review',
        'updated_at',
        'deleted_at',
        'team.name',
    ];

    public $filterable = [
        'id',
        'project.name',
        'post.title',
        'created_at',
        'statues',
        'confirmation',
        'note',
        'review',
        'updated_at',
        'deleted_at',
        'team.name',
    ];

    protected function serializeDate(DateTimeInterface $date)
    {
        return $date->format('Y-m-d H:i:s');
    }

    public function registerMediaConversions(Media $media = null): void
    {
        $thumbnailWidth  = 50;
        $thumbnailHeight = 50;

        $thumbnailPreviewWidth  = 120;
        $thumbnailPreviewHeight = 120;

        $this->addMediaConversion('thumbnail')
            ->width($thumbnailWidth)
            ->height($thumbnailHeight)
            ->fit('crop', $thumbnailWidth, $thumbnailHeight);
        $this->addMediaConversion('preview_thumbnail')
            ->width($thumbnailPreviewWidth)
            ->height($thumbnailPreviewHeight)
            ->fit('crop', $thumbnailPreviewWidth, $thumbnailPreviewHeight);
    }

    public function project()
    {
        return $this->belongsTo(Project::class);
    }

    public function post()
    {
        return $this->belongsTo(Post::class);
    }

    public function getDesignAttribute()
    {
        return $this->getMedia('design_design')->map(function ($item) {
            $media                      = $item->toArray();
            $media['url']               = $item->getUrl();
            $media['thumbnail']         = $item->getUrl('thumbnail');
            $media['preview_thumbnail'] = $item->getUrl('preview_thumbnail');

            return $media;
        });
    }

    public function getCreatedAtAttribute($value)
    {
        return $value ? Carbon::createFromFormat('Y-m-d H:i:s', $value)->format(config('project.datetime_format')) : null;
    }

    public function getStatuesLabelAttribute($value)
    {
        return static::STATUES_RADIO[$this->statues] ?? null;
    }

    public function getConfirmationLabelAttribute($value)
    {
        return static::CONFIRMATION_RADIO[$this->confirmation] ?? null;
    }

    public function getReviewLabelAttribute($value)
    {
        return static::REVIEW_RADIO[$this->review] ?? null;
    }

    public function getUpdatedAtAttribute($value)
    {
        return $value ? Carbon::createFromFormat('Y-m-d H:i:s', $value)->format(config('project.datetime_format')) : null;
    }

    public function getDeletedAtAttribute($value)
    {
        return $value ? Carbon::createFromFormat('Y-m-d H:i:s', $value)->format(config('project.datetime_format')) : null;
    }

    public function team()
    {
        return $this->belongsTo(Team::class);
    }
}

what shall I do please ???

0 likes
4 replies
LaryAI's avatar
Level 58

The error message you're encountering indicates that there is a foreign key constraint violation when you're trying to save a Design instance. This typically happens when you're trying to insert a row into a table with a foreign key that does not exist in the referenced table.

In your submit method within the Livewire component, you have the following lines:

$this->design->project_id = $this->selectedProjectId;
$this->design->post_id = $this->selectedProjectId;
$this->design->save();

It looks like you're mistakenly assigning the selectedProjectId to both project_id and post_id. This could be the cause of the foreign key constraint violation if the selectedProjectId does not exist in the posts table.

Here's what you should do:

  1. Ensure that $this->selectedProjectId contains a valid project_id that exists in the projects table.
  2. Ensure that you have a valid post_id selected that exists in the posts table. You might need to have a separate property for the selected post_id (e.g., $this->selectedPostId).

Here's the corrected code for the submit method:

public function submit()
{
    $this->validate();

    // Assign the selected project ID to the design instance
    $this->design->project_id = $this->selectedProjectId;

    // Ensure you have a selectedPostId property that holds the selected post ID
    $this->design->post_id = $this->selectedPostId;

    $this->design->save();
    $this->syncMedia();
    event(new DesignCreated($this->design));

    return redirect()->route('admin.designs.index');
}

Make sure you also update the rules method to validate the selectedPostId if you add it, and ensure that the updatedSelectedProjectId method correctly sets the available posts for the selected project.

Lastly, double-check your database to ensure that the foreign key constraints are correctly set up and that the post_id you're trying to assign actually exists in the posts table.

gych's avatar

Make sure you are using a correct post id that exists in the post db table

In your code i see that you're setting the value of project_id and post_id to the same value selectedProjectId. Which might be the cause of your issue.

    $this->design->project_id = $this->selectedProjectId;
    $this->design->post_id = $this->selectedProjectId;

Make sure that $this->design->post_id has the correct value of the actual post your referring to.

Michael Fayez's avatar

@gych yes I make it it's temporarly solved the issue but the post didn't saved in the database please help what is the mistake ?

<?php

namespace App\Http\Livewire\Design;

use App\Models\Design;
use App\Models\Post;
use App\Models\Project;
use App\Models\Team;
use Livewire\Component;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
use App\Listeners\Design\DesignCreatedEmail;
use App\Events\Design\DesignCreated;


class Create extends Component
{
    public Design $design;

    public $posts;
    public $projects;
    public $post;
    public $post_id;
    public $project;

    public array $mediaToRemove = [];

    public array $listsForFields = [];

    public array $mediaCollections = [];

    public $selectedProjectId = null;
    
    public $selectedPostId = null;

    public function addMedia($media): void
    {
        $this->mediaCollections[$media['collection_name']][] = $media;
    }

    public function removeMedia($media): void
    {
        $collection = collect($this->mediaCollections[$media['collection_name']]);

        $this->mediaCollections[$media['collection_name']] = $collection->reject(fn ($item) => $item['uuid'] === $media['uuid'])->toArray();

        $this->mediaToRemove[] = $media['uuid'];
    }

    protected function syncMedia(): void
    {
        collect($this->mediaCollections)->flatten(1)
            ->each(fn ($item) => Media::where('uuid', $item['uuid'])
                ->update(['model_id' => $this->design->id]));

        Media::whereIn('uuid', $this->mediaToRemove)->delete();
    }

    public function mount(Design $design)
    {
        $this->design = $design;
        $this->projects = Project::all(); // Load all projects
        $this->posts = collect();
        $this->initListsForFields();
    }

    public function updatedSelectedProjectId($projectId)
    {
        $this->posts = Post::where('project_id', $projectId)->get();
    }



    public function render()
    {
        return view('livewire.design.create');
    }


    public function submit()
{
    $this->validate();

    // Assign the selected project and post IDs to the design instance
    $this->design->project_id = $this->selectedProjectId;
    $this->design->post_id = $this->selectedPostId;
    $this->design->save();
    $this->syncMedia();
    event(new DesignCreated($this->design));

    return redirect()->route('admin.designs.index');
}




    protected function rules(): array
    {
        return [
            'design.project_id' => [
                'integer',
                'exists:projects,id',
                'nullable',
            ],
            'design.post_id' => [
                'integer',
                'exists:posts,id',
                'nullable',
            ],
            'mediaCollections.design_design' => [
                'array',
                'required',
            ],
            'mediaCollections.design_design.*.id' => [
                'integer',
                'exists:media,id',
            ],
            'design.statues' => [
                'nullable',
                'in:' . implode(',', array_keys($this->listsForFields['statues'])),
            ],
            'design.confirmation' => [
                'nullable',
                'in:' . implode(',', array_keys($this->listsForFields['confirmation'])),
            ],
            'design.note' => [
                'string',
                'nullable',
            ],
            'design.review' => [
                'nullable',
                'in:' . implode(',', array_keys($this->listsForFields['review'])),
            ],
            'design.team_id' => [
                'integer',
                'exists:teams,id',
                'required',
            ],
        ];
    }

    protected function initListsForFields(): void
    {
        $this->listsForFields['project']      = Project::pluck('name', 'id')->toArray();
        $this->listsForFields['post']         = Post::pluck('title', 'id')->toArray();
        $this->listsForFields['statues']      = $this->design::STATUES_RADIO;
        $this->listsForFields['confirmation'] = $this->design::CONFIRMATION_RADIO;
        $this->listsForFields['review']       = $this->design::REVIEW_RADIO;
        $this->listsForFields['team']         = Team::pluck('name', 'id')->toArray();
    }
}
gych's avatar

Ok nice that this solved the initial issue, I see that you've already created a new thread for the new issue that you've encountered. You can close this thread by marking it as solved.

Please or to participate in this conversation.