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

ziben69's avatar

Truncate table with foreign key

Hello guys, I have problem with overwriting the table, because I combine it with another using a foreign key.

I am trying to do draggable table, and when I drag row I get error 500 in my console:

"message": "SQLSTATE[42000]: Syntax error or access violation: 1701 Cannot truncate a table referenced in a foreign key constraint (`photography`.`photos`, CONSTRAINT `photos_business_id_foreign` FOREIGN KEY (`business_id`) REFERENCES `photography`.`businesses` (`id`)) (SQL: truncate `businesses`)",

I have two tables - photos, and business. In Photo model it looks:

class Photo extends Model
{
protected $fillable = [
        'filename',
        'business_id',
    ];
public function business()
    {
        return $this->belongsTo(Business::class, 'business_id');
    }
}

In Business model:

class Business extends Model
{
    protected $fillable = [
        'title',
        'description',
        'order',
        'visiblity',
        'lang'
    ];

    public function photos()
    {
        return $this->hasMany(Photo::class); 
    }
}

Its all ok, but I need help with BusinessController function:

    public function updateAll(Request $request)
    {
        Business::truncate();

        foreach($request->businesses as $business){
            Business::create([
                'id' => $business['id'],
                'title' => $business['title'],
                'description' => $business['description'],
                'order' => $business['order'],
                'visiblity' => $business['visiblity'],
                'lang' => $business['lang'],
            ]);
        }
        return response('Update Successful.',200);
    }

Here is foreign key migration fragment:

...
public function up()
    {
        Schema::table('photos', function(Blueprint $table){
            $table->integer('business_id')->unsigned()->change();
            $table->foreign('business_id','photos_business_id_foreign')->references('id')->on('businesses');
        });
    }
...

How can I handle photos? I need update business_id, but don't know how... So much thanks!

0 likes
29 replies
mushood's avatar

instead of truncate, you can use

Business::where('id', '>', 0)->delete();

This will delete all business AS LONG AS you don't have any photos with this business id

You can do something like this.

    public function updateAll(Request $request)
    {
        Photo::truncate();
    Business::where('id', '>', 0)->delete();

        foreach($request->businesses as $business){
            Business::create([
                'id' => $business['id'],
                'title' => $business['title'],
                'description' => $business['description'],
                'order' => $business['order'],
                'visiblity' => $business['visiblity'],
                'lang' => $business['lang'],
            ]);
        }
        return response('Update Successful.',200);
    }

BE CAREFUL. This will delete all photos

mvd's avatar

Hi @ziben69,

I would not use a foreign key (when I see this code) I should reset the business_id, do a update on Photo model before 'Business::truncate()'.

public function updateAll(Request $request)
    {
    Photo::update(['business_id' => 0]);
        Business::truncate();

@mushood you are also deleting all the photos (from the database) i don't know if this is the intention.

ziben69's avatar

@MUSHOOD - Thanks, but I can't delete these photos. I need to change the business_id column in the Photo table. Maybe I can do something like that?

ziben69's avatar

@MVD - "message": "Non-static method Illuminate\Database\Eloquent\Model::update() should not be called statically",

STEREOH's avatar

The main question here is @ziben69 do you want to keep your relationships between your photos and your buisnesses ?

if yes, you can't delete your buisness because there's no way you will be able to attach your photos back with the updated ( re-created in your case) buisnesses.

I would strongly advise to update when it's possible rather than delete everything and re-create if you have relationships.

If you don't care however,

you can simply add onDelete('set null'); on your foreign key. This will set your buisness_idon photos to null when you delete your buisness.

If you do that don't forget to add ->nullable()to your buisness_id in photos.

public function up()
    {
        Schema::table('photos', function(Blueprint $table){
            $table->integer('business_id')->unsigned()->change()->nullable();
           $table->foreign('business_id','photos_business_id_foreign')->references('id')->on('businesses')->onDelete('set null');
        });
    }
STEREOH's avatar

@ZIBEN69 - Based on what ? Is the buisness['id'] in your request the same Id you had before the deletion ?

If it is, so I guess it's okay to do so.

ziben69's avatar

@STEREOH - The ID should remain unchanged. However, only the "order" column should be changed, but I don't know why it doesn't work.

Now I have something like that:

   public function updateAll(Request $request)
    {
        Photo::update(['business_id' => 0]);
        Business::truncate();

        foreach($request->businesses as $business){
            Business::create([
                'id' => $business['id'],
                'title' => $business['title'],
                'description' => $business['description'],
                'order' => $business['order'],
                'visiblity' => $business['visiblity'],
                'lang' => $business['lang'],

            ]);
        }
        return response('Update Successful.',200);
    }

and error:

"message": "Non-static method Illuminate\Database\Eloquent\Model::update() should not be called statically",
STEREOH's avatar

With the edit I made on my first answer, this should work properly. ( the ->onDelete('set null') ; part )

If it doesn't, describe me what is wrong.

And put back this code to where it was at the begining.

   public function updateAll(Request $request)
    {
        Business::truncate();

        foreach($request->businesses as $business){
            Business::create([
                'id' => $business['id'],
                'title' => $business['title'],
                'description' => $business['description'],
                'order' => $business['order'],
                'visiblity' => $business['visiblity'],
                'lang' => $business['lang'],
            ]);
        }
        return response('Update Successful.',200);
    }
mvd's avatar

@ziben69 if only the order column needs to be changed, just do a update instead of the truncate and create what @stereoh wrote.

STEREOH's avatar

@ZIBEN69 - Sorry didn't see you had an error earlier , just delete the Photo::update line it's not relevant if you have ->onDelete('set null')

By the way you need to php artisan migrate:fresh since you changed your migration

STEREOH's avatar

@MVD - I totally agree with you and I strongly advised that in my first post but if that's what @ziben69 wants.

1 like
ziben69's avatar

@STEREOH -

I added in migration:

    public function up()
    {
        Schema::table('photos', function(Blueprint $table){
            $table->integer('business_id')->unsigned()->change()->nullable();
            $table->foreign('business_id','photos_business_id_foreign')->references('id')->on('businesses')->onDelete('set null');
        });
    }

and back with controller function updateAll to:

    public function updateAll(Request $request)
    {
        Business::truncate();

        foreach($request->businesses as $business){
            Business::create([
                'id' => $business['id'],
                'title' => $business['title'],
                'description' => $business['description'],
                'order' => $business['order'],
                'visiblity' => $business['visiblity'],
                'lang' => $business['lang'],
            ]);
        }
        return response('Update Successful.',200);
    }

php artisan migrate:fresh done

and again I have error:

"message": "SQLSTATE[42000]: Syntax error or access violation: 1701 Cannot truncate a table referenced in a foreign key constraint (`photography`.`photos`, CONSTRAINT `photos_business_id_foreign` FOREIGN KEY (`business_id`) REFERENCES `photography`.`businesses` (`id`)) (SQL: truncate `businesses`)",
gorakhyadav's avatar

Try something like this.

    DB::statement('SET FOREIGN_KEY_CHECKS=0;');
    DB::table('table1')->truncate();
    DB::table('table2')->truncate();
    DB::statement('SET FOREIGN_KEY_CHECKS=1;');
1 like
STEREOH's avatar

Indeed you can't truncate.

try

\App\Buisness::whereNotNull('id')->delete();

instead of

Business::truncate();
ziben69's avatar

But tell me how we can update photo, now we are still deleting it

@stereoh - at the moment we are deleting photos after moving the row in the table. Now how do I load this picture from scratch?

gorakhyadav's avatar

update your migration like this and then refresh your migration

public function up()
    {
        Schema::create('photos', function(Blueprint $table) 
            {
    $table->increments('id');
    $table->string('filename');
    $table->integer('business_id')->unsigned();
    $table->foreign('business_id')->references('id')->on('business')->onDelete('cascade');
    $table->timestamps();
         });
     }
STEREOH's avatar
STEREOH
Best Answer
Level 18

Well that's easy you just update them ( I also changed the way you delete buisnesses ):

public function updateAll(Request $request)
{
   foreach($request->businesses as $business){

   Buisness::find($buisness['id'])->delete();

   $newBuisness = Business::create([
      'id' => $business['id'],
      'title' => $business['title'],
      'description' => $business['description'],
      'order' => $business['order'],
      'visiblity' => $business['visiblity'],
      'lang' => $business['lang'],
   ]);

   $orphanPhotos = Photo::whereNull('buisness_id')->get();

   foreach($orphanPhotos  as $photo)
      {
         $photo->update(['buisness_id' => $newBuisness->id]);
      }
   }
   
   return response('Update Successful.',200);
}

You should try and search before asking for all made solutions though. It's not good for your learning if you get it served on a plate.

STEREOH's avatar

@ZIBEN69 - you are not deleting your photos , just not reffering to your new buisness in it.

STEREOH's avatar

As a final note , I will show you how easy all of this would have been if you juste updated your models.

public function updateAll(Request $request)
{
   foreach($request->businesses as $business){

      $buisnessModel = Buisness::find($buisness['id']);
      $buisnessModel->title = $business['title'];
      $buisnessModel->description = $business['description'];
      $buisnessModel->order = $business['order'];
      $buisnessModel->visiblity = $business['visiblity'];
      $buisnessModel->lang = $business['lang'];

      $buisnessModel->save();
   }
   
   return response('Update Successful.',200);
}

and no changes in your migrations.

You should probably do this.

1 like
ziben69's avatar

@STEREOH - That's work! Yeah time to analyze what you wrote.

<3 Thank you and everyone for help!

mvd's avatar

@stereoh yes thats a much better approach for only a update. And if only the order field needs a update

$buisnessModel = Buisness::find($buisness['id']);
$buisnessModel->order = $business['order'];
$buisnessModel->save();
1 like
princeoo7's avatar

This is insane. Only an update was needed but i wonder why OP first thought of deleting the data for business and recreate it :/ Well i hope he got what he was looking for :)

Please or to participate in this conversation.