【问题标题】:Detach doesn't trigger cascade分离不会触发级联
【发布时间】:2015-04-13 17:28:07
【问题描述】:

我有一个多对多的关系。枢轴模型有很多孩子。当我在多对多上调用分离时,我还需要删除枢轴模型的孩子。我想使用 onDelete('cascade'),但这似乎不起作用。我也试过这个:http://laravel-tricks.com/tricks/using-model-events-to-delete-related-items,但这似乎也不起作用。两者都不起作用可能是因为没有触发销毁事件。

当我调用 detach 时如何让孩子们删除有什么想法吗?

这是我的一些代码,以防我犯了错误:

我的支点模型:

    Schema::create('beer_distributions', function(Blueprint $table)
    {
        $table->increments('id');
        $table->integer('beer_id');
        $table->integer('distributor_id');

枢轴模型的孩子:

    Schema::create('kegs', function(Blueprint $table)
    {
        $table->increments('id');
        $table->integer('beer_distribution_id');
        $table->dropForeign('kegs_beer_distribution_id_foreign');
        $table->foreign('beer_distribution_id')
            ->references('id')
            ->on('beer_distributions')
            ->onDelete('cascade');

我不知道是否有办法挽救这种方法。我打电话给同步,然后试图删除孩子,没有意识到父母已经走了,让孩子无法访问。:

        $attachments = $beer->distributors()->sync(Input::get('distributors'));
        foreach ($attachments['detached'] as $distributor_id) {
            BeerDistribution::where('beer_id', '=', $id)
                                ->where('distributor_id', '=', $distributor_id)->first()->destroy();
        }

更新: 需要明确的是,我有四个正在使用的模型。啤酒与经销商具有多对多关系。枢轴模型 BeerDistributions 有许多桶。当我调用 sync 来更新啤酒经销商时,BeerDistributions 会自动删除,我希望同时删除小桶。

这是我的一些模型:

class Beer extends Eloquent {

    public function distributors()
    {
        return $this->belongsToMany('Distributor', 'beer_distributions');
    }

Beer ^ manyToMany with Distributor:

class Distributor extends Eloquent {

  public function beers()
  {
      return $this->belongsToMany('Beer', 'beer_distributions');
  }

枢轴模型...

class BeerDistribution extends Eloquent {

    public function kegs()
    {
       return $this->hasMany('Keg', 'beer_distribution_id');
    }

有很多小桶:

class Keg extends Eloquent {

  public function beerDistribution()
  {
    return $this->belongsTo('BeerDistribution');
  }

【问题讨论】:

    标签: php laravel orm cascade


    【解决方案1】:

    这里似乎对数据透视表、分离和级联有些混淆。

    基本上,分离方法应该是你所需要的。它所做的只是通过belongsToMany() 关系管理数据透视表。

    因此,如果您执行 $keg->distributors()->detach([1,2,3]) 并且 $keg->id 为 5,它将搜索并删除分配器为 1、2 或 3 且桶 ID 为 5 的枢轴中的项目。在大多数情况下,您应该甚至不需要数据透视表的雄辩模型。 detach()attach()sync() 将为您处理该表。

    级联删除可能是导致您出现问题的原因,因为您将其倒退。在这种情况下,级联键上的删除将放在数据透视表上。这意味着当您删除父项(桶或分配)时,数据透视表中属于该父项的那些项目将被自动删除。这样可以避免在表中出现孤立数据。

    为什么我说你这样做是因为你把钥匙放在你的kegs 表上,这意味着当数据透视表中的一个项目被删除时,你的小桶也会被删除。这很糟糕,根本不是你想要的。当您的小桶被删除时,您想从数据透视表中删除项目。

    删除该键并在您的架构中创建beerDistributions 添加两个看起来像这样的键... $table->foreign('beer_id')->references('id')->on('beers')->onDelete('Cascade'); $table->foreign('distribution_id')->references('id')->on('distributors')->onDelete('Cascade');

    如果您有一个正在级联删除您的分销商表上的密钥,也将其删除。数据透视表上应该只有这些外键。

    编辑:看到您想如何删除小桶,看起来好像您在数据透视表中引用了错误的列。

    $table->foreign('id')
        ->references('beer_distribution_id')
        ->on('beer_distributions')
        ->onDelete('cascade');
    

    【讨论】:

    • 我可能没有正确解释这一点,我用更多信息更新了我的问题。从数据透视表中删除项目时,我确实想删除小桶。我希望这会自动发生(可能在我调用同步/分离时绑定)。
    • 您的密钥正在引用表 beerDistributions,但您的架构正在创建表 beer_distributions。会不会是这个问题?
    • 这可能是个问题,但它仍然无法正常工作。 BeerDistributions 被删除,但桶没有被删除。
    猜你喜欢
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 2015-01-19
    • 1970-01-01
    • 2013-04-03
    • 2019-02-14
    • 2022-01-25
    相关资源
    最近更新 更多