Reputation: 29
I want to ask a question. I am developing a project in Laravel 8. I have 3 tables products (id, name), urls (id, page_id, request_id) and product_url (product_id, url_id, site_id). When a product or url is deleted, I can delete it from the product_url table. There is no problem, but when I delete a data from the product table, I want to delete all the urls connected to that product from the product_url table, but it did not work, although I gave it onDelete ('cascade') in the product_url table. :( is there an easy way to achieve this?
Products migration:
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Urls migration:
Schema::create('urls', function (Blueprint $table) {
$table->id();
$table->text('page_url');
$table->text('request_url')->nullable();
$table->timestamps();
});
Product_Url Pivot migration:
Schema::create('product_url', function (Blueprint $table) {
$table->foreignId('product_id')->constrained();
$table->foreignId('url_id')->constrained()->cascadeOnDelete();
$table->unsignedBigInteger('site_id');
});
Product Model:
use HasFactory;
protected $fillable = ['name'];
protected $hidden = ['created_at','updated_at'];
public function url()
{
return $this->belongsToMany(Url::class)
->withPivot('site_id');
}
public function sites()
{
return $this->belongsToMany(Site::class, 'product_url')
->withPivot('product_id','url_id');
}
Urls Model:
use HasFactory;
protected $fillable = ['page_url','request_url'];
protected $hidden = ['created_at','updated_at'];
public function products()
{
return $this->belongsToMany(Product::class)
->withPivot('site_id');
}
public function sites()
{
return $this->belongsToMany(Site::class, 'product_url')
->withPivot('product_id','url_id');
}
public function urls()
{
return $this->belongsToMany(self::class)
->withPivot('url_id');
}
Products Controller:
public function destroy($id)
{
$product = Product::find($id);
$product->url()->detach();
$product->delete();
return redirect()->route('product.index');
}
Urls Controller:
public function destroy($id)
{
$Url = Url::find($id);
$Url->products()->detach();
$Url->delete();
return redirect()->route('url.index');
}
Upvotes: 2
Views: 694
Reputation: 1961
To remove a many-to-many relationship record, use the detach
method. The detach
method will delete the appropriate record out of the intermediate table; however, both models will remain in the database:
//Detach a single url from product
$product->urls()->detach($urlId);
//Detach All urls from the product
$product->urls()->detach();
For convenience, detach also accept arrays of IDs as input:
$product->urls()->detach([1, 2, 3]);
And then you can delete your product model and related model.
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Product $product
* @return \Illuminate\Http\Response
*/
public function destroy(Product $product)
{
$product->url()->detach();
$product->url()->delete();
$product->delete();
return redirect()
->route('product.index')
->withSuccess('Product başarılı şekilde silindi.');
}
Upvotes: 0
Reputation: 29
solved the problem. I added the url to the ProductController destroy method with with, then I deleted the relation table first with $ product->url()->delete(), then I cleared the pivot table and deleted the product from the product table.
public function destroy($id)
{
$product = Product::with('url')->find($id) ?? abort(404,'Product Bulunamadı');
$product->url()->delete();
$product->url()->detach();
$product->delete();
return redirect()->route('product.index')->withSuccess('Product başarılı şekilde silindi.');
}
Upvotes: -1