首页 > 解决方案 > 在 Laravel 中更新数据透视表

问题描述

我正在尝试用斑点更新表格。我想用 livewire 点击一下,但没有任何效果,所以我认为只使用我已经拥有的 Laravel 控制器中的方法会更容易。之所以使用附加和分离,是因为我的视图中有两个表,一个包含所有站点,另一个包含我正在尝试更新的站点,其中包含已经在工作簿中的站点。以我现在的方法,我可以更新除现场之外的所有内容,但我不知道为什么。工作簿和站点之间是多对多的关系,并且点是数据透视表中的一个额外字段。

 <form action="{{route('admin.workbooks.update', [$client_id, $workbook_id])}}" method="POST" enctype="multipart/form-data">
          @csrf
          @method('PUT')

            <div class="form-group">
                            <label for="">Media Schedule Name</label>
                            <input type="text" class="form-control" name="wrkb_name" value="{{$workbook_name}}">
            </div>
            <table class="table-auto w-full mb-6">
          <thead>
            <tr>
              <th class="px-4 py-2"></th>
                @if($showLetter)
              <th wire:click="sortBy('call_letter')" style="cursor: pointer;" class="px-4 py-2">Call Letter @include('partials.sort-icon',['field'=>'call_letter'])</th>
              @endif           
              <th  style="cursor: pointer;" class="px-4 py-2">Spots @include('partials.sort-icon',['field'=>'spots'])</th>
              
            </tr>
          </thead>
          <tbody>
            @foreach($selected_stations as $key => $selected_station)

              <tr>
                <td class="border px-4 py-2">
                    <input  name="selected_stations[]" wire:model="selected_already" value="{{ $selected_station->id }}" type="checkbox">
                </td>
              
                @if($showLetter)
                <td class="border px-4 py-2">{{$selected_station->call_letter}}</td>
                @endif
                
                <td class="border px-4 py-2">
                    <input name="spot" type="text" class="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500" value="{{$selected_station->pivot->spot}}" placeholder="{{$selected_station->pivot->spot}}"></td>
                <td>
              </td>
              </tr>
            @endforeach
          </tbody>
        </table>
<br>
        <table class="table-auto w-full mb-6">
          <thead>
            <tr>
              <th class="px-4 py-2"></th>
              
                @if($showLetter)
              <th wire:click="sortBy('call_letter')" style="cursor: pointer;" class="px-4 py-2">Call Letter @include('partials.sort-icon',['field'=>'call_letter'])</th>
              @endif
            </tr>
          </thead>
          <tbody>
            @foreach($stations as $key => $station)
              <tr>
                <td class="border px-4 py-2">
                    <input  name="stations[]" wire:model="selected" value="{{ $station->id }}" type="checkbox">
                </td>
                @if($showLetter)
                <td class="border px-4 py-2">{{$station->call_letter}}</td>
                @endif
               
                <td>
              </td>
              </tr>
            @endforeach
          </tbody>
        </table>
    
        @else
            <p class="text-center">Whoops! No users were found </p>
        @endif
        <div class="w-full flex pb-10" >
            <div class="w-1/6 relative mx-1 space-x-6">
                <button class="block appearance-none w-full bg-black border border-gray-200 text-white py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500">Edit Media Schedule</button>
            </div>
        </div>
</form>
    public function update(UpdateWorkbookRequest $request,Client $client, Workbook $workbook)
    {
        $workbook->update($request->only('wrkb_name'));
        $workbook->stations()->detach($request->input('selected_stations', []));
        $workbook->stations()->attach($request->input('stations', []));
        $workbook->stations()->updateExistingPivot('spot', []);
        return redirect()->route('admin.workbooks.edit', [$client->id, $workbook->id])->with('success', 'Successfully Edited the Workbook');
    
    }

这就是其中一种关系的样子,尽管我认为这没有多大帮助

    public function workbooks()
    {
      return $this->belongsToMany(\App\Models\Workbook::class, 'station_workbook', 'station_id', 'workbook_id')->withPivot('spot')->withTimestamps();;
    }

我还发现我可以使用类似的东西,但我只想更新那个特定的记录,从这段代码看来,它似乎更新了该站的每个实例,无论是什么工作簿,它无论如何都不起作用。

        foreach($workbook->stations as $key => $station){
            dd($station->workbooks);
            $station->workbooks()->updateExistingPivot($key, ['spot' => $request ->spot]);
        }

我也试过这个没有成功

        $usedStations=$request->input('stations', []);

        $workbook->update($request->only('wrkb_name'));
        $workbook->stations()->detach($request->input('selected_stations', []));
        $workbook->stations()->attach($request->input('stations', []));
        foreach($usedStations as $usedStation)
        {
            $station_id = Station::where('id',$usedStation)->value('id');
            $workbook->stations()->updateExistingPivot($station_id, ['spot' => $request ->spot]);
        }

标签: laravel

解决方案


引用 Laravel 文档:(链接

将关系附加到模型时,您还可以传递要插入到中间表中的附加数据数组

所以,你可以这样做:

$workbook->stations()->attach($request->input('stations', []),['spot'=>$request->input('spot')]);

更新

目前,在您的代码中,只有“spot”字段的单个值被传递给请求。将其更改为:

<input name="spot[{{$selected_station->id}}]" type="text" class="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500" value="{{$selected_station->pivot->spot}}" placeholder="{{$selected_station->pivot->spot}}"></td>

update() 方法应该是:

        public function update(UpdateWorkbookRequest $request,Client $client, Workbook $workbook)
            {
                $workbook->update($request->only('wrkb_name'));
                $workbook->stations()->detach($request->input('selected_stations', []));
                $workbook->stations()->attach($request->input('stations', []));
//take only the spot values of selected_stations that were unchecked
                $spots = array_diff_key($request->input('spot',[]), array_flip($request->input('selected_stations',[])));

                foreach($spots as $station_id=>$spot_value){
                            $workbook->stations()->updateExistingPivot($station_id, ['spot'=>$spot_value]);
    
    }
                return redirect()->route('admin.workbooks.edit', [$client->id, $workbook->id])->with('success', 'Successfully Edited the Workbook');
            
            }

推荐阅读