在数据透视表 laravel 中删除行和插入行

Posted

技术标签:

【中文标题】在数据透视表 laravel 中删除行和插入行【英文标题】:Deleting rows and insert row in pivot table laravel 【发布时间】:2014-12-16 00:48:36 【问题描述】:

您好,当出现以下情况时,我正在尝试更新我的 tagtask 表(数据透视表):

例如,我们已经有一个包含 3 个标签的任务,例如营销、开发、会计。现在我们要编辑该任务并删除这 3 个标签并添加 1 个名为 Cooking 的标签。

所以我已经想到的是从 tagtask 表中删除这 3 个标签并添加标签“烹饪” 在 tagtask 表中。此外,我不会从标签表中删除标签,因为可能有一些任务使用市场营销、开发或会计标签。

不幸的是,关于第一部分我的想法我无法实现。为了向您展示我的尝试,我将首先向您展示我的一段代码:

Form::model($task,array('route'=>array('user.tasks.update', $task->id), 'method'=>'put'))
    <ul>
        <li>
                Form::label('tag', 'tags')
                <input type="text" name="tag_name" class="form-control" value='@foreach($task->tagtask as $tt)$tt->tag['tag_name'] @endforeach'>
        </li>
        <li>
                Form::submit('Edit Task',  array('class' => 'btn btn-default'))
        </li>
    </ul>
Form::close()

这是我的TaskController.php,其中包含以下代码:

<?php 
public function update($id)
    
        $task = Task::findOrFail($id);
        $str = Input::get('tag_name');
        //Split string by a regular expression
        $arrayTags = preg_split('/[, ;]/', $str);

        $tt_current = Tagtask::where('id_task', $id)->get();
        $tags_raw = Tag::all();
        $tags =  array();

        foreach($tags_raw as $tag) 
           
            $tags[$tag->tag_name] = $tag->id;
        

        foreach($arrayTags as $tag) 
        

            if(!isset($tags[$tag]))
                //The tag doesn't exist. So we store a tag and get a new ID.
                        $id_tag=DB::table('tags')->insertGetId(
                                array('tag_name' => $tag)
                                );

                        $data_TagTask= array(
                                'id_task' => $id,
                                'id_tag' => $id_tag
                                );

                        $id_tagtask=DB::table('tagtasks')->insertGetId($data_TagTask);
                        $row= DB::table('tagtasks')->where('id', $id_tagtask)->first();

             else 
                //The tag does exist
                foreach($tt_current as $tt) 
                   //the following below is maybe wrong..
                    if ($tt->id_tag ==  $tags[$tag] && $tt->id_task == $row->id_task ) 
                        Tagtask::destroy($row->id_task);
                    
                    //$tags[$tag->tag_name] = $tag->id;
                    //if(isset($tags_current[$id_task]))
                    //unset($tags_current[$id_task]);
                
               
        
        //print_r($tags)
        //die();
        return Redirect::route('user.tasks.index');
    

所以我使用该代码实现的是,我可以删除视图中的 3 个标签(如前所述)并添加一个新标签进行更新。新的标签然后存储在tagtask表和tag表中,但问题是旧的3个标签还在tagtask表中。虽然他们应该被删除..有人可以帮助我吗?很高兴我在等你的答复。不管怎样,谢谢你的回答。

【问题讨论】:

【参考方案1】:

您应该为此使用sync。也许我错过了什么,但代码应该是这样的:

public function update($id)

    $task = Task::findOrFail($id);
    $str = Input::get('tag_name');
    //Split string by a regular expression
    $arrayTags = preg_split('/[, ;]/', $str);

    $tagIds = [];
    foreach ($arrayTags as $tag) 
        // here you can apply trim or skipping empty tags
        $fTag = Tag::firstOrCreate(['tag_name' => $tag]);
        $tagIds[] = $fTag->id;
    

    $task->tags()->sync($tagIds);

    return Redirect::route('user.tasks.index');

当然,tags 模型需要有 tags 关系

【讨论】:

您好,再次感谢您的回答!您或其他人能否也向我展示它的查询生成器版本?如果问得太多,那我真的不介意。是因为好奇呵呵。我会在我睡后测试你的代码,因为此刻我真的很累.. @superkytoz 如果你使用 Eloquent,你应该使用它,因为它更容易完成一些任务。使用查询生成器,您可能会得到和您一样长的代码 我在使用sync()方法时出现以下错误:调用未定义方法Illuminate\Database\Query\Builder::sync() 我也做了截图:i.imgur.com/eJ6CPIv.png这是我在控制器中使用的代码: $task->tagtask()->sync($tagIds);这是我的模型任务中的 tagtask() 方法: public function tagtask() //oneToMany return $this->hasMany('Tagtask', 'id_task', 'id'); 【参考方案2】:

我为感兴趣的人提供解决方案。唯一的更改是在 TaskController.php 中进行的。下面是带有cmets的代码,方便大家理解:

<?php 
public function update($id)
    
        $str = Input::get('tag_name');
        //Split string by a regular expression
        $inputTags = preg_split('/[, ;]/', $str);

        $tt_current = Tagtask::where('id_task', $id)->get();
        $oldTaskTagsToDestroy = array();

        $tags_raw = Tag::all();
        $tags =  array();

        foreach($tt_current as $item) 
           //id_tag is the key with the tagtaskID as value.
            $oldTaskTagsToDestroy[$item->id_tag] = $item->id;
        

        foreach($tags_raw as $tag) 
           //tag_name is the key with the tagID as value.
            $tags[$tag->tag_name] = $tag->id;
        

        foreach($inputTags as $tag) 
        
            if(!isset($tags[$tag]))
                /* At first in $tag lives the name of the tag that was given through
                input from a user. After that we return the id through the insertGetId() method and
                put in $tags[$tag]*/
                $tags[$tag] = DB::table('tags')->insertGetId(
                    array('tag_name' => $tag)
                );

                //for example tagtask ID 40 exists, so we don't execute the body of the if statement
            if(!isset($oldTaskTagsToDestroy[ $tags[$tag] ]))

                $data_TagTask= array(
                        'id_task' => $id,
                        'id_tag' => $tags[$tag]
                        );

                DB::table('tagtasks')->insertGetId($data_TagTask);

             else 
                /*So we remove the key and the value of tagtask ID 40, because it's again present in the new input.
                We must do this, so that the old tasktags ID's will not be deleted from the tagtask table.*/
                unset( $oldTaskTagsToDestroy[ $tags[$tag] ] );
        
        //And here we remove old tagtask ID's that aren't present anymore/again with the new input. So we delete them from the database.
        foreach($oldTaskTagsToDestroy as $key => $value) 
           
                Tagtask::destroy($value);
        

        return Redirect::route('user.tasks.index');
    

说实话,我得到了实习主管的帮助。我是一家构建 Web 应用程序的公司的实习生。我正在尽我最大的努力成为一名优秀的程序员

【讨论】:

以上是关于在数据透视表 laravel 中删除行和插入行的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 中删除行和插入行的最佳方法是啥

在laravel中将数据插入数据透视表

Excle数据透视表如何禁用数据透视表的总计行/列

如何在 Laravel 中使用附加或同步方法在数据透视表中插入多个值

laravel:更新或创建(更新插入)数据透视表

Laravel 数据透视表批量插入多个字段