Laravel删除记录会影响新记录的顺序

时间:2019-04-30 09:32:26

标签: laravel eloquent record

我可以成功删除票证并将记录从数据库中删除。如果我有两个票证“票证1和票证2”,我可以很高兴地删除票证1,因为它是第一张票证,并且可以删除票证2,因为它是票证1之后的下一张票证(任何顺序!)

但是,我有一个有趣的老问题:如果我不按连续降序删除票证

以这些票证为例:

门票1-创建时间10:00 票证2-时间创建于10:15 票证3-时间创建于10:30

因此,如果我删除票证3(因为这是最后创建的票证),删除票证2,删除票证1并删除中间票证“票证2”,则在尝试创建另一个票证时收到错误消息。创建了新票证,但是未填充“作者”和“组织”字段,当我打开票证时,出现“无消息错误”-因为票证无法完全创建。

当使用空的“作者”和“组织”字段以及“无消息” laravel错误创建此新故障单时,该ID将被添加一个原来位于其下方的故障单。因此,例如,如果我删除ID为2的票证2(仅保留ID为1和3的票证),则当我创建另一个票证时,它会收到一个ID为4的正确ID,但在phpMyAdmin中,该4显示当然高于3,而不是高于3。同样,ID为'3'的票证的'slug'属性也将递增为'ticket-title-2',但这也不应该发生。但是,我认为这与票证增量无关,因为如果没有该方法(如图所示)在票务模型中),问题仍然存在。

我还认为这与我使用的删除方法有关,因此尝试使用$ ticket-> forceDelete()而不是$ ticket-> delete(),但这似乎不起作用。我尝试过我的create方法,但是经过许多小时的调试,我仍在努力寻找问题出在哪里。但是,我确实知道问题出在票证被删除时的订购,但是我不知道在哪里触发了这个问题。

路线

Route::delete('ticket/{ticket}', 'AdminController@delete')->name('admin.delete');

门票-存储功能

public function store()
    {
        if (Auth::user()->organisation == "Bournemouth University") {
            $ticketCode = "BU";
        } else {
            $ticketCode = "NHS";
        }

        $attributes = request()->validate([
            'title' => ['required', 'min: 2'],
            'description' => ['required'],
            'subject_area' => ['required']
        ]);

        Ticket::create($attributes);
        $slug = str_slug(Ticket::get()->last()->title, '-');

        Ticket::get()->last()->update(['code' => $ticketCode, 'user_id' => Auth::user()->id, 'slug' => $slug, 'author' => Auth::user()->username]);

        $slug = Ticket::get()->last()->slug;

        return redirect()->route('ticket.show', $slug);
    }

管理控制器-删除方法

public function delete(Ticket $ticket){
        $ticket->delete();
        return redirect('/');
    }

机票页面-删除表格

<div class="modal fade" id="delete" tabindex="-1" role="dialog">
                            <div class="modal-dialog" role="document">
                                <div class="modal-content">
                                    <div class="modal-header">
                                        <h4>Are you sure you want to delete this post?</h4>
                                    </div>
                                    <div class="modal-body">
                                        <form id="delete-post" method="POST" action="{{route('admin.delete', $slug->slug) }}">
                                            @csrf
                                            @method('DELETE')
                                            <div style="text-align: center">
                                                <button type="submit" class="btn btn-success"
                                                        id="confirm-del" data-dismiss="modal"
                                                        style="font-weight: bold;">Yes
                                                </button>
                                                <button type="button" class="btn btn-danger" data-dismiss="modal"
                                                        style="font-weight: bold;">No
                                                </button>
                                            </div>
                                        </form>
                                        <script type="text/javascript">
                                            $(function(){
                                                $('#confirm-del').on('click', function(){
                                                    $('#delete-post').submit();
                                                });
                                            });
                                        </script>
                                    </div>
                                </div>
                            </div>
                        </div>

机票模型-弹头增量方法

 public function setSlugAttribute($value){
        if(static::whereSlug($slug = str_slug($value))->exists()){
            $slug = $this->incrementSlug($slug);
        }

        $this->attributes['slug'] = $slug;
    }

    public function incrementSlug($slug){
        $firstSlug = $slug;
        $count = 2;

        while(static::whereSlug($slug)->exists()){
            $slug = "{$firstSlug}-" . $count++;
        }
        return $slug;
    }

很抱歉,很抱歉。我希望有人能向我指出正确的方向,指出我可能出问题的地方或如何纠正此问题。

1 个答案:

答案 0 :(得分:1)

我不知道它是否可以解决您的问题,但是每次您写

Ticket::get()->last()

您正在进行大型数据库查询。确实,这翻译为“让我得到所有结果,而得到的结果中给我最后一个”。如果要获取最新消息(按created_at顺序),可以使用:

Ticket::latest()->first()

但是,每次调用它也是一个查询。

出于多种原因(包括并发性,速度,可维护性),我建议一次性完成所有操作:

public function store()
{
    if (Auth::user()->organisation == "Bournemouth University") {
        $ticketCode = "BU";
    } else {
        $ticketCode = "NHS";
    }

    $attributes = request()->validate([
        'title' => ['required', 'min: 2'],
        'description' => ['required'],
        'subject_area' => ['required']
    ]);

    // Now, populate the attributes before creating the ticket.
    $attributes['slug'] = str_slug(Ticket::get()->last()->title, '-');
    $attributes['code'] = $ticketCode;
    $attributes['user_id'] = Auth::user()->id;
    $attributes['author'] = Auth::user()->username;

    $ticket = Ticket::create($attributes);

    // And we get the slug directly from the ticket
    return redirect()->route('ticket.show', $ticket->slug);
}

PS: 对该代码的更多改进可能是:

  • 使用事件来设置子弹,而不是变异器。
  • 使用用户和票证之间的关系并删除用户名字段。