简体   繁体   中英

Deleting rows and insert row in pivot table laravel

Hi I'm trying to update my tagtask table (pivot table) when the following situation occurs:

So for example we already have a task that has 3 tags with it for example marketing, development, accountancy. Now we want to edit that task and remove those 3 tags and add 1 tag called cooking.

So what I have already in mind is to delete those 3 tags from tagtask table and to add the tag 'cooking' in the tagtask table. Also I'm not deleting tags from the tags table, because there are maybe tasks that uses a marketing or a development or a accountancy tag.

Unfortunately about the first part what I had in mind I couldn't realize it. To show you what I have tried, I will first show you a piece of code of my view:

{{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()}}

And here is my TaskController.php with the following piece of code:

<?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');
    }

So what I have achieved with that code is, that I can remove the 3 tags (as I mentioned earlier) in the view and add a new tag to update. The new tag is then stored in the tagtask table and tag table, but the problem is that the old 3 tags are still in tagtask table. While they should be removed.. Can someone help me, please? Gladly I'm waiting on your answer. Anyway thanks for your answer.

You should use sync for that. Maybe I missed something but the code should be something like this:

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');
}

of course you need to have tags relation for Task model

I have the solution for those who are interested. The only changes were made in TaskController.php. Here is the code with comments, so that you can understand it much easier:

<?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');
    }

To be actually honest I had received help from my internship supervisor. I'm a trainee in a company who build web applications. I'm doing my very best to be a good programmer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM