Laravel Eloquent ORM - Many to Many Delete Pivot Table Values left over

前端 未结 4 1678
抹茶落季
抹茶落季 2020-12-28 13:06

Using Laravel, I have the following code

$review = Review::find(1);
$review->delete();

Review has a many to many relationsh

相关标签:
4条回答
  • 2020-12-28 13:48

    $review->product()->sync([]) also works.

    However $review->product()->detach() is much more explicit.

    0 讨论(0)
  • 2020-12-28 13:51

    The detach method is used to release a relationship from the pivot table, whilst delete will delete the model record itself i.e. the record in the reviews table. My understanding is that delete won't trigger the detach implicitly. You can use model events to trigger a cleanup of the pivot table, though, using something like:

    Review::deleting(function($review)
    {
        $review->product()->detach()
    }
    

    Also, I would suggest that the relationship would be a one to many, as one product would have many reviews, but one review wouldn't belong to many products (usually).

    class Review extends \Eloquent {
        public function product()
        {
            return $this->belongsTo('Product');
        }
    }
    
    class Product extends \Eloquent {
        public function reviews()
        {
            return $this->hasMany('Review');
        }
    }
    

    Of course, this would then require that you tweak your database structure. If you wanted to leave the database structure and your current relationships as they are, the other option would be to apply a foreign key constraint on the pivot table, such that when either a review or product is removed, you could cascade the delete on the pivot table.

    // Part of a database migration
    $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
    $table->foreign('review_id')->references('id')->on('reviews')->onDelete('cascade');
    

    Edit: In adding the constraint, you push the cleanup work onto the database, and don't have to worry about handling it in code.

    0 讨论(0)
  • 2020-12-28 13:59

    Simpler Steps:

    In this example an Account has many Tags:

    To delete the Tags, then the Account do this:

    // delete the relationships with Tags (Pivot table) first.
    $account->find($this->accountId)->tags()->detach();
    
    // delete the record from the account table.
    $account->delete($this->accountId);
    

    On the Pivot Table make sure you have ->onDelete('cascade');

    $table->integer('account_id')->unsigned()->index();
    $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
    
    $table->integer('tag_id')->unsigned()->index();
    $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
    
    0 讨论(0)
  • 2020-12-28 14:06

    i guess you have a error in your models relationship conception, the product has many reviews but the review associated with one product so you have here one to many relationship. but in general the answer in the general case will be using:

    $product->reviews()->sync([]);
    
    0 讨论(0)
提交回复
热议问题