Я получаю внутреннюю ошибку 500 при попытке передать именованный маршрут с двумя параметрами в моем контроллере.

Поэтому, когда я устанавливаю имя маршрута с одним параметром, он работает безупречно, но когда я передаю именованный маршрут с двумя параметрами, я получаю ошибку 500 в своей консоли, которая выглядит так: GET http://127.0.0.1:8000/admin/packages/package-programs/kathmandu/action?query= 500 (Internal Server Error).

<?php

namespace App\Http\Controllers\AdminVisible;

use Illuminate\Http\Request;
use Illuminate\Support\Str;
use App\Program;
use App\Package;
use DB;

class PackageProgramController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    public function index($packageSlug)
    {
        $showCounts = Program::count();
        $packages = Package::firstOrFail();
        return view('admin.pages.packageprogram',compact('showCounts','packageSlug','packages'));      
    }

    function action($packageSlug,Request $request)
    {
        if($request->ajax())
        {
         $output = '';
         $query = $request->get('query');
         if($query != '')
         {
          $data = DB::table('programs')
            ->where('id', 'like', '%'.$query.'%')
            ->orWhere('day', 'like', '%'.$query.'%')
            ->orWhere('Package_Type', 'like', '%'.$query.'%')
            ->orWhere('title', 'like', '%'.$query.'%')
            ->orderBy('id', 'desc')
            ->get();
            
         }
         else
         {
          $data = DB::table('programs')
            ->orderBy('id', 'desc')
            ->get();
         }
         $total_row = $data->count();

         if($total_row > 0)
         {
          foreach($data as $row)
          {
            $packageProgram = ['packageProgram' => $row->id];
            $route = route('PackageProgram.edit',['packageSlug' => $packageSlug, 'packageProgram' => $packageProgram]);
           $output .= '
            
           <tr>
           <th scope="row"><input type="checkbox" name="ids[]" class="selectbox" value="'.$row->id.'" onchange="change()"></th>
            <td onClick="location.href=\''.$route.'\' " style="cursor: pointer">'.$row->id.'</td>
            <td onClick="location.href=\''.$route.'\' " style="cursor: pointer">'.$row->day.'</td>
            <td onClick="location.href=\''.$route.'\' " style="cursor: pointer">'.$row->title.'</td>
            <td onClick="location.href=\''.$route.'\' " style="cursor: pointer">'.$row->description.'</td>

           </tr>
           ';
          }
         }
         else
         {
          $output = '
          <tr>
           <td align="center" colspan="12">No Data Found</td>
          </tr>
          ';
         }
         $data = array(
          'table_data'  => $output,
          'total_data'  => $total_row
         );
   
         echo json_encode($data);
        }
    }

    public function create($packageSlug, Package $package) 
    {
        return view('admin.create.createPackageProgram',compact('packageSlug','package'));
    }

    public function store($packageSlug,Request $request) 
    {
        $packages = Package::where('slug', $packageSlug)->firstOrFail();
        $data = request()->validate([
            'day' => 'required',             
            'title' => 'required',
            'description' => 'required', 
        ]);
        $packages->program()->create($data);
        switch ($request->input('action')) {
        case 'preview':
            return redirect()->intended(route('PackageProgram',$packageSlug))->with('message', 'Package Program has been added.');
            break;
        
        default:
            return redirect()->back()->with('message', 'Package Program has been added.');
            break;
        }
    }

    public function edit($packageSlug,Program $packageProgram,Package $package)  
    {
        return view('admin.edit.editPackageProgram',compact('packageSlug','packageProgram','package'));
    }

    public function update($packageSlug, Program $packageProgram)
    {
        $data = request()->validate([
            'day' => 'required',
            'title' => 'required',
            'description' => 'required',
        ]);
        $packageProgram->update($data);
        return redirect()->intended(route('PackageProgram',$packageSlug))->with('message', 'Package Program has been updated.');
    }

    public function delete(Request $request) {
        $data = request()->validate([
            'deleteSelected' => 'required',
        ]);
        $id = $request->get('ids');
        $data = DB::delete('delete from programs where id in ('.implode(",",$id).')');
        return redirect()->back()->with('message', 'Testimony has been deleted.');
    }
}
    

Мой файл блейда выглядит примерно так:

@extends('layouts.app')
@section('style')
    <link href="{{ asset('css/Admin/sql-data-viewer.css') }}" rel="stylesheet">   
    <style></style>
@endsection
@section('content')
<section class="data-viewer">
  <div class="d-flex justify-content-between px-3">
    <h3 class="text-white">Select {{$package->Package_Name}} {{$package->Package_Type}} Days to change</h3>
  <a href="{{ route('PackageProgram.create',$packageSlug) }}"><button type="button" class="btn add-data text-white rounded-pill">Add Day &nbsp;<i class="fas fa-plus"></i></button></a>
  </div>
  <form>
    @csrf
    @method('DELETE')
    @if(session()->has('message'))
    <div class="alert alert-success">
        {{ session()->get('message') }}
    </div>
    @endif 
    <div class="d-flex justify-content-between selectDelete">
      <div class="delete pl-3 mt-3 mb-3">
        <label for="deleteSelected">Action:</label>
        <select name="deleteSelected" id="deleteSelected" class="@error('deleteSelected') is-invalid @enderror" name="deleteSelected" >
          <option disabled selected>---------</option>
          <option>Delete Selected Package Program</option>
        </select>
        <button formaction="{{ route('PackageProgram.delete',$package) }}" formmethod="POST" type="submit" class="go" id="deleleGo" onclick="deleteBtn()">Go</button> 
        &nbsp;&nbsp;<span id="selected">0</span> of {{$showCounts}} selected
        @error('deleteSelected')
          <span class="invalid-feedback" role="alert">
              <strong>{{ $message }}</strong>
          </span>
        @enderror
        <strong id="selectError">You must check at least one checkbox</strong>             
      </div>
      <div class="search pr-3 mt-3 mb-3">
        <label for="search">Search:</label>
        <input id="search" type="text" color="#000" class="rounded @error('search') is-invalid @enderror" name="search" value="{{ old('search') }}" autocomplete="search" placeholder="Search">
        @error('search')
          <span class="invalid-feedback" role="alert">
              <strong>{{ $message }}</strong>
          </span>
        @enderror 
      </div>
    </div>
    <table class="table table-hover table-striped table-dark">
      <thead>
        <tr>
          <th scope="col"><input type="checkbox" id="checkHead" class="selectall"></th>
          <th scope="col">Id</th>
          <th scope="col">Day</th>
          <th scope="col">Title</th>
          <th scope="col">Description</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
  </form>
</section>
@endsection

@section('script')
  <script src="{{ asset('/js/sqlData.js') }}"></script>
  <script>
    $(document).ready(function(){
    
    fetch_data();
    
    function fetch_data(query = '')
    {
    $.ajax({
      url:"{{ route('PackageProgram.action',$packageSlug) }}",
      method:'GET',
      data:{query:query},
      dataType:'json',
      success:function(data)
      {
      $('tbody').html(data.table_data);
      }
    })
    }
    
    $(document).on('keyup', '#search', function(){
    var query = $(this).val();
    fetch_data(query);
    });
    });
    function checkboxError(){
      var number = document.querySelectorAll('.selectbox:checked').length;
      if(number  == 0) {
        var a = document.getElementById("selectError").style.display = "block";
        return false;
      }
    }
    window.addEventListener('DOMContentLoaded', (event) => {
      var deleteBtn = document.getElementById("deleleGo");
      deleteBtn.onclick = checkboxError;
    });
  </script>
@endsection

Итак, мой файл маршрута выглядит примерно так:

        Route::prefix('package-programs')->group(function() {
            Route::get('/', 'AdminVisible\packagePackageProgramController@index')->name('PackagePrograms');
            Route::get('/action', 'AdminVisible\packagePackageProgramController@action')->name('PackagePrograms.action');
            Route::prefix('{packageSlug}')->group(function() {
                Route::get('/', 'AdminVisible\PackageProgramController@index')->name('PackageProgram');
                Route::get('/action', 'AdminVisible\PackageProgramController@action')->name('PackageProgram.action');
                Route::get('/create', 'AdminVisible\PackageProgramController@create')->name('PackageProgram.create');
                Route::post('/create', 'AdminVisible\PackageProgramController@store')->name('PackageProgram.store');
                Route::delete('/delete','AdminVisible\PackageProgramController@delete')->name('PackageProgram.delete');
                Route::get('/{packageProgram}/edit', 'AdminVisible\PackageProgramController@edit')->name('PackageProgram.edit');
                Route::patch('/{packageProgram}', 'AdminVisible\PackageProgramController@update')->name('PackageProgram.update');
            });
        });

Может быть, я не знаю, как передать именованный маршрут с двумя параметрами, но в моем блейд-файле я делал это так, и там это работает. Это что-то другое, что должно быть сделано в контроллере.


person Nutan Panta    schedule 26.08.2020    source источник
comment
Небольшое примечание о вашем промежуточном программном обеспечении в конструкции, в вашем случае вы можете и должны назначить auth промежуточное программное обеспечение для группы маршрутизации, как это Route::middleware(['auth'])->group(function () {... проверьте здесь. Таким образом, ваш код становится чище, удобнее в сопровождении и лучше соответствует шаблонам проектирования. О вопросе: ваша функция action назначается как метод get в маршрутах, но вы используете Http\Request в качестве параметра функции, поэтому измените свой маршрут на сообщение, чтобы вы могли получить параметры запроса из формы и добавить параметр uri Route::post('/action/{your_param}',...   -  person Arman    schedule 27.08.2020
comment
Но чем снова проверьте это, это плохой шаблон дизайна для использования сообщения с аргументами uri, я заметил, что ваша форма содержит только query arg так сделай так, чтобы он получал Route вот так Route::get('/action/{slug}/{query}', ...   -  person Arman    schedule 27.08.2020
comment
И снова избегайте смешивания php + html, бэкэнд должен возвращать только данные, которые интерфейс, чем обрабатывает, однако он хочет, чтобы с js он был более удобным в сопровождении и снова хорошим шаблоном дизайна.   -  person Arman    schedule 27.08.2020
comment
@Arman, то, что я сделал, - это поиск в реальном времени с помощью ajax. Я знаю, что некоторые из моих тренировок могут быть плохими, так как я новичок и учусь, но не могли бы вы сказать мне, как я могу это исправить или сделать это по-другому и лучше? Я также вставлю свой клинок. файл. Но проблема в моем $route только потому, что если я удалю, он работает отлично, и у меня есть он и на других страницах, у которых есть маршрут с одним параметром, где он работает отлично.   -  person Nutan Panta    schedule 27.08.2020
comment
$.ajax({ url:"{{ route('PackageProgram.action') }}", method:'GET', data: { 'slug': {{ $packageSlug }}, 'query': query },.. и измените свой маршрут на Route::get('/action/{slug}/{query}', .. и функцию function action($packageSlug, $query) проверьте с помощью dd(), если все аргументы верны   -  person Arman    schedule 27.08.2020
comment
@Арман, дай мне попробовать   -  person Nutan Panta    schedule 27.08.2020
comment
@Arman Я думаю, что URL-адрес неверен, потому что нам также нужно передать параметр   -  person Nutan Panta    schedule 27.08.2020


Ответы (1)


Сначала начните с лезвия (пожалуйста, проверьте комментарии):

@extends('layout')
@section('content')
    <div class="row">
        <table class="table table-hover table-striped table-dark" id="slugTb">
            <thead>
            <tr>
                <th scope="col"><input type="checkbox" id="checkHead" class="selectall"></th>
                <th scope="col">Id</th>
                <th scope="col">Day</th>
                <th scope="col">Title</th>
                <th scope="col">Description</th>
            </tr>
            </thead>
        <tbody></tbody>
        </table>
    </div>
@endsection

@section('scripts')
    <script>
        $(document).ready(function() {
            var query = 'damnSon';
            $.ajax({
                url: "{{ route('test.action') }}",
                method: 'GET',
                data: {
                    'slug': '{{ $packageSlug }}',
                    'query': query
                },
                dataType: 'json',
            })
                .done(function(data) {
                    console.log(data) //use console.log to debug
                    $('#slugTb tbody').html(data.table_data); //set table id so that you don't miss the right one
            })
                .fail(function(err) {
                    console.log(err) //in case if error happens
            })
                .always(function() {
                    console.log( "complete" ); //result despite the response code
            });
        });

    </script>
@endsection

Вы использовали устаревший метод jquery, например success check
Лучше используйте эти три: done, fail,always

Следующий маршрут web.php:

Route::get('action', ['as' => 'test.action', 'uses' => 'TestController@action']);

В вашем случае лучше использовать пакет параметров Request, чтобы вы могли добавить столько параметров, сколько хотите.

Следующий контроллер:

function action(Request $request)
{
    $total_row = 1;

    $packageSlug = $request->get('slug'); //names that you set in ajax data tag: {'slug': '{{ $packageSlug }}','query': query}
    $query = $request->get('query');
    $output = '<tr>
       <td align="center" colspan="1">' . $packageSlug . '</td>
       <td align="center" colspan="1">' . $query .'</td>
      </tr>';

        $data = array(
            'table_data'  => $output,
            'total_data'  => $total_row
        );

        return response()->json($data);
}

Вы должны вернуть что-то из контроллера, чтобы блейд мог показать эти данные, и json закодировал их, чтобы js мог их проанализировать. Вот почему return response()->json($data);

Другой способ:

маршрут:

Route::get('/action/{slug}/{query}',['as' => 'test.action', 'uses' => 'TestController@action']);

blade скрипт:

<script>
    $(document).ready(function() {
        var query = 'damnSon';
        $.ajax({
            url: 'action/{{ $packageSlug }}/' + query,
            method: 'GET',
            dataType: 'json',
        })
            .done(function(data) {
                console.log(data) //use console.log to debug
                $('#slugTb tbody').html(data.table_data); //set table id so that you don't miss the right one
        })
            .fail(function(err) {
                console.log(err) //in case if error happens
        })
            .always(function() {
                console.log( "complete" ); //result despite the response code
        });
    });

</script>

и контроллер:

function action($slug, $query)
{
    $total_row = 1;

    $packageSlug = $slug;
    $query = $query;
    $output = '<tr>
       <td align="center" colspan="1">' . $packageSlug . '</td>
       <td align="center" colspan="1">' . $query .'</td>
      </tr>';

        $data = array(
            'table_data'  => $output,
            'total_data'  => $total_row
        );

        return response()->json($data);
}

Не рекомендуется только потому, что вы вручную вводите маршрут в запросе ajax: url: 'action/{{ $packageSlug }}/' + query если ваш маршрут изменится, вы должны изменить его в js.

person Arman    schedule 28.08.2020
comment
Вам не нужно проверять, является ли запрос ajax if($request->ajax()), если вы не хотите использовать эту функцию action для других вызовов, но лучше использовать отдельные методы для вызовов ajax и других типов, что является хорошей практикой. Также настоятельно рекомендуем прочитать официальную документацию по laravel, там все объяснено и есть много маршрутизации, проверки, красноречия и т. д. . Примеры - person Arman; 28.08.2020
comment
Также обратите внимание, что в тегах script вы можете использовать переменную php(laravel) только в кавычках '{{ $packageSlug }}' - person Arman; 28.08.2020