У меня есть три модели, Advertiser
, PtcAd
и PtcCampaign
. При удалении Рекламодатель Я хочу удалить все связанные PtcAds и PtcCampaigns. Рекламодатель имеет множество PtcCampaigns через PtcAds.Удалить hasManyThrough relatioship rows using Laravel's Eloquent
Рекламодатель Модель
use SoftDeletes;
protected $dates = ['deleted_at'];
public function ptcAds()
{
return $this->hasMany('App\PtcAd');
}
public function ptcCampaigns()
{
return $this->hasManyThrough('App\PtcCampaign', 'App\PtcAd');
}
public function delete()
{
$this->ptcAds()->delete();
// I'VE TRIED WITH AND WITHOUT THIS
$this->ptcCampaigns()->delete();
return parent::delete();
}
PtcAd Модель
use SoftDeletes;
protected $fillable = ['advertiser_id', 'title'];
protected $dates = ['deleted_at'];
public function advertiser()
{
return $this->belongsTo('App\Advertiser');
}
public function ptcCampaigns()
{
return $this->hasMany('App\ptcCampaign');
}
public function delete()
{
$this->ptcCampaigns()->delete();
return parent::delete();
}
PtcCampaign Модель
use SoftDeletes;
public $timestamps = false;
protected $fillable = ['ptc_ad_id', 'clicks'];
protected $dates = ['paused_at', 'deleted_at'];
public function ptcAd()
{
return $this->belongsTo('App\PtcAd');
}
Мои тесты:
public function test_delete_advertiser()
{
$advertiser = factory(Advertiser::class)->create();
$ptcAd = factory(PtcAd::class)->create(['advertiser_id' => $advertiser->id]);
$ptcCampaign = factory(PtcCampaign::class)->create(['ptc_ad_id' => $ptcAd->id]);
$this->assertTrue($advertiser->delete());
$this->assertFalse(Advertiser::all()->contains($advertiser));
$this->assertFalse(PtcAd::all()->contains($ptcAd));
// THE FOLLOWING TEST DOESN'T WORK!
$this->assertFalse(PtcCampaign::all()->contains($ptcCampaign));
}
// ALL OF THE FOLLOWING TESTS WORK!
public function test_delete_ad()
{
$ptcAd = factory(PtcAd::class)->create();
$ptcCampaign = factory(PtcCampaign::class)->create(['ptc_ad_id' => $ptcAd->id]);
$this->assertTrue($ptcAd->delete());
$this->assertFalse(PtcAd::all()->contains($ptcAd));
$this->assertFalse(PtcCampaign::all()->contains($ptcCampaign));
}
$this->assertFalse(PtcCampaign::all()->contains($ptcCampaign))
в тесте test_delete_advertiser()
не удается, почему?
У меня есть больше тестов, чтобы убедиться, что все отношения работают, поэтому я действительно не знаю, что может быть неправильно. Моей следующей попыткой было бы сделать foreach
в методе delete() рекламодателя, но, возможно, есть что-то более простое, и я хочу понять, почему это не работает.
Это делает его! Спасибо! Теперь у меня есть другой связанный вопрос, так как модель 'PtcAd' имеет метод' delete() ', настроенный для удаления' PtcCampaign 'в отношении, почему мне нужно вызвать' $ this-> ptcCampaigns() -> delete(); 'из модели« Рекламодатель »? Разве это не цепь? – DanVeira
Когда вы делаете '$ this-> ptcAds() -> delete()', он создает запрос и удаляет строки, чтобы он вызывал класс построителя запросов 'delete'. Но если вы удалите 'ptcAds' с помощью' foreach', тогда он вызывает функцию delete класса Model, и он также удалит 'ptcCampaigns'. –