69586


# 環境

PHP7.3  
Laravel5.5  
PosgreSQL

# やりたいこと

  1. 詳細ページにあるコメントの削除ボタンを押す。
  2. ログインページに飛ぶので、ログインする。
  3. 詳細ページにリダイレクトされると同時にコメントが削除されている。

# 現状

  1. 2.までは上手くいくが3.の時にNo message というエラーが出力される。

[![画像の説明をここに入力](https://i.stack.imgur.com/bbsgh.png)](https://i.stack.imgur.com/bbsgh.png)

[![画像の説明をここに入力](https://i.stack.imgur.com/YoaEF.png)](https://i.stack.imgur.com/YoaEF.png)

# 考慮して欲しいこと

  1. 認証した状態で、削除ボタンを押すと削除はできます。
  2. 現在、あるユーザーが投稿したコメントを、別のユーザーが削除できてしまうという問題も起きていますが、こちらは後に実装する予定なのでいったん無視でお願いします。
  3. コメントに返信できる機能もありますが、返信機能も同様に未認証で返信の削除ボタンを押すと"No message"というエラーが発生します。
  4. 外部キー制約を設定しているので、コメントを削除するとそれに紐づく返信も自動的に削除されます。

# 検証環境

未認証でのコメント削除の検証はこちらでできます、 ただローカル開発環境と同じエラーメッセージは出力されていません。

<https://song-picture-mamp.work/songs/3>

# 試したこと

すみません。試したことに入るのか分かりませんが"No Message"というエラーメッセージがヒントにならなかったので,”Laravel 未認証
削除機能”等で調べてみましたが該当しそうな記事はありませんでした。

# 該当コード

[code]

    //web.php
    Route::group(['middleware' => 'auth:user'], function () {
     Route::get('comments/create', 'CommentController@create')->name('comments.create');
     Route::post('comments', 'CommentController@store')->name('comments.store');
     Route::post('comments/{id}', 'CommentController@destroy')->name('comments.destroy');
     Route::get('/replies/create', 'ReplyController@create')->name('replies.create');
     Route::post('/replies', 'ReplyController@store')->name('replies.store');
     Route::post('/replies/{id}', 'ReplyController@destroy')->name('replies.destroy');
    });
    
[/code]

[code]

    //　CommentController
    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use App\Http\Requests\CommentRequest;
    use App\Comment;
    
    class CommentController extends Controller
    {
     /**
      * Display a listing of the resource.
      *
      * @return \Illuminate\Http\Response
      */
     public function index()
     {
      //
     }
    
     /**
      * Show the form for creating a new resource.
      *
      * @return \Illuminate\Http\Response
      */
     public function create()
     {
      $q = \Request::query();
      // dd($q['song_id']);
      return view('comments.create', [
       'song_id' => $q['song_id'],
      ]);
     }
    
     /**
      * Store a newly created resource in storage.
      *
      * @param  \Illuminate\Http\Request  $request
      * @return \Illuminate\Http\Response
      */
     public function store(CommentRequest $request)
     {
      // dd($request);
      $comment = new Comment;
    
      $input = $request->only($comment->getFillable());
      // dd($input);
      $comment = $comment->create($input);
      return redirect()->route('songs.show', ['id' => $comment->song_id]);
     }
    
     /**
      * Remove the specified resource from storage.
      *
      * @param  int  $id
      * @return \Illuminate\Http\Response
      */
     public function destroy($id)
     {
      // dd($id);
      $comment = Comment::find($id);
      // dd($comment);
      $comment->delete();
    
      return redirect()->route('songs.show', ['id' => $comment->song_id]);
     }
    }
    
[/code]

[code]

    create_comment_table
    
    <?php
    
    use Illuminate\Support\Facades\Schema;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;
    
    class CreateCommentsTable extends Migration
    {
     /**
      * Run the migrations.
      *
      * @return void
      */
     public function up()
     {
      Schema::create('comments', function (Blueprint $table) {
       $table->increments('id');
    
       $table->integer('user_id')->unsigned();
       $table->integer('song_id')->unsigned();
    
       $table->string('comment')->nullable();
    
       $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
       $table->foreign('song_id')->references('id')->on('songs')->onDelete('cascade');
       $table->timestamps();
      });
     }
    
     /**
      * Reverse the migrations.
      *
      * @return void
      */
     public function down()
     {
      Schema::dropIfExists('comments');
     }
    }
    
    
[/code]

[code]

    // songs/show.blade.php
    
    @extends('layouts.app')
    @section('content')
    <div class="container">
     <div class="row">
      <h3 class="text-center form-group">
       {{ $song->title }}
      </h3>
      <div class="form-group text-primary">
       {{ $song->detail }}
      </div>
    
      <div class="form-group">
       @if (!empty($song['file_name']))
       <img src="{{ asset('/storage/img/'.$song->file_name) }}">
       @else
       <img src="{{ asset('/public_images/black_no_image.png')}}">
       @endif
      </div>
      <div class="form-group">
       <like :song-id="{{ json_encode($song->id) }}" :user-id="{{ json_encode($userAuth->id) }}"
        :default-Liked="{{ json_encode($defaultLiked) }}" :default-Count="{{ json_encode($defaultCount) }}">
       </like>
      </div>
     </div>
    
     <div class="form-group">
      <span>コメント一覧</span>
      <a href="{{ route('comments.create', ['song_id' => $song->id]) }}" class="btn btn-warning mt-5">コメントする</a>
     </div>
    
     @foreach ($song->comments as $comment)
     <div class="panel panel-success">
      <div class="panel-heading">
       登録者:{{ $comment->user->name }}
    
      // ⭐️　ここがコメント部分です。
       {{Form::model($comment, ['route' => ['comments.destroy', $comment->id]])}}
       <a href="{{ route('replies.create', ['comment_id' => $comment->id]) }}" class="btn btn-info mt-5">返信する</a>
       <button onclick="return confirm('本当に削除しますか？')" class="btn btn-danger">削除する</button>
       {{Form::close()}}
    　//
    
      </div>
      <p class="panel-body">{{ $comment->comment }}</p>
      @foreach($comment->replies as $rep)
      @if($comment->id === $rep->comment_id)
      <div class="well">
       登録者：{{ $rep->name }} |
       <span> {{ $rep->reply }} </span>
       <form action="{{ route('replies.destroy',$rep) }}" method="post">
        {{ csrf_field() }}
        <button onclick="return confirm('本当に削除しますか？')" class="btn btn-danger reply-rm-button">削除する</button>
       </form>
      </div>
      @endif
      @endforeach
      </p>
     </div>
     @endforeach
    </div>
    @endsection
    
    
[/code]

[code]

    // モデル、Comment.php
    ?php
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    use App\Models\User;
    use App\Models\Reply;
    use App\Models\Song;
    
    class Comment extends Model
    {
     protected $fillable = [
      'user_id', 'song_id', 'comment'
     ];
    
     public function user()
     {
      return $this->belongsTo(User::class, 'user_id');
     }
    
     public function replies()
     {
      return $this->hasMany(Reply::class, 'comment_id', 'id');
     }
    
     public function song()
     {
      return $this->belongsTo(Song::class, 'song_id', 'id');
     }
    }
    
[/code]

全コード <https://github.com/masal9pse/song-picture-mamp>  
本番環境 https://song-picture-mamp.work/

何かアドバイスがあればよろしくお願いします。


CC BY-SA 4.0
2020-08-15T09:34:03.910
69577
2020-08-15T15:30:02.880
2020-08-15T15:30:02.880
36424
36424
question
php laravel
Laravel5 未認証で削除ボタンを押すと"No Message"というエラー


エラーの内容を示しているものは`No
Message`ではなく、むしろその上に小さな赤色で表示されている`MethodNotAllowedHttpException`と思われます（もちろん本来は`No
Message`の部分になにがしかの詳細でわかりやすいメッセージが表示されるべきです）。つまり、許可されていないHTTP
Method（GETとかPOSTとか）でリクエストが送信されたということです。

ところが、質問のソースコードでは削除用のパスはPOSTに設定されていますし、`Form`はデフォルトでは[POSTを使用します](https://readouble.com/laravel/5.0/ja/html.html)。では何がいけないのかというと、`Route::group`で`['middleware'
=> 'auth:user']`という指定がなされていることだと考えました。

この指定によって、グループ内のパスには[認証済みのユーザしかアクセスできないようになります](https://readouble.com/laravel/5.5/ja/authentication.html)。未認証で曲のページにアクセスすると、`songs/show.blade.php`の内容がレンダリングされます。そのままユーザが操作すると`comments.destroy`や`replies.create`に移動しますが、それらのrouteには未認証ユーザからアクセスできず、GETもPOSTも許可されない状態になっています。そしてエラーが発生します。

このように考えると、以下の記述ともつじつまが合います。

>   1. 認証した状態で、削除ボタンを押すと削除はできます。
>

>   3. コメントに返信できる機能もありますが、返信機能も同様に未認証で返信の削除ボタンを押すと"No message"というエラーが発生します。
>

「ユーザが未認証ならログインさせる」処理（フレンドリーフォワーディング）を実装するには、たとえばBladeテンプレートでログイン状態によってリンク先を変更するなどの方法が考えられます。


CC BY-SA 4.0
2020-08-15T14:14:12.430
69586
2020-08-15T14:14:12.430
7500
69577
answer