【Laravel】ポートフォリオのブラッシュアップに挑戦

はじめに

以下の記事に記載した項目をポートフォリオで実装チャレンジしてみました。

【Laravel】初学者が更なる高みを目指して学ぶべきこと

今まで参考にしたチュートリアルからは、以下のようにブラッシュアップしてきました。

v1 基本的な削除・編集機能追加

v2 削除・編集の権限周り考慮(自身の投稿しか編集できないように実装)

v3 検索機能・評価の★マーク(oldヘルパーなど駆使)実装

改善点の洗い出し

改善点

①レビュー詳細画面へ未ログインユーザーがアクセスできるようにする。⇒今回チャレンジ

現状は、詳細画面へアクセスするとログイン画面に遷移してしまう。

(②本番環境にて編集・削除ページへアクセスできない。)

改修チャレンジ

①レビュー詳細画面へ未ログインユーザーがアクセスできるようにする。

ルーティングの確認。

Auth::routes();
Route::get('/' , 'ReviewController@index')->name('index');
Route::group(['middleware' => 'auth'], function () {
    Route::get('/show/{id}', 'ReviewController@show')->name('show');
    Route::resource('users', 'UsersController',['only' => ['index', 'show', 'edit', 'update']]);
    Route::get('/review', 'ReviewController@create')->name('create');
    Route::post('/review/store', 'ReviewController@store')->name('store');
    Route::get('/edit/{id}', 'ReviewController@edit')->name('edit');
    Route::post('/update','ReviewController@update')->name('update');
    Route::get('/delete/{id}', 'ReviewController@destroy');
});
Route::get('/show/{id}', 'ReviewController@show')->name('show');をミドルウェアグループの外に移動させる。
Auth::routes();
Route::get('/' , 'ReviewController@index')->name('index');
Route::get('/show/{id}', 'ReviewController@show')->name('show');
Route::group(['middleware' => 'auth'], function () {
    Route::resource('users', 'UsersController',['only' => ['index', 'show', 'edit', 'update']]);
    Route::get('/review', 'ReviewController@create')->name('create');
    Route::post('/review/store', 'ReviewController@store')->name('store');
    Route::get('/edit/{id}', 'ReviewController@edit')->name('edit');
    Route::post('/update','ReviewController@update')->name('update');
    Route::get('/delete/{id}', 'ReviewController@destroy');
});

詳細画面へアクセスしたところ、Trying to get property 'id' of non-objectとidプロパティがないとエラー。

show.blade.php記載の該当エラー箇所。下記、削除部分を消せば表示された。

@if ($review->user->id == Auth::user()->id) //--削除

    <a href="{{ route('edit', ['id' => $review->id ]) }}" class='btn btn-info btn-back mb20'>編集する</a>

@endif //--削除

違うユーザーの投稿編集ボタンを押すと、403エラー画面に飛ぶようコントローラーで実装済みなので使えなくはない。

public function edit($id)
{
    $user_id = Review::where('id', $id)->value('user_id');
    if ($user_id !== Auth::user()->id) {
        abort(403);
    }
    $review = Review::where('id', $id)->where('status', 1)->first();
    return view('edit', compact('review'));
 }

とはいえ、編集ボタンが誰でも表示されるのが気に入らない。。。(@if文は消さずに従来通り、自分の投稿のみ表示させたい。)

@if文を復活させる。

ポリシー作成。

$ php artisan make:policy ReviewPolicy --model=Review

ReviewPolicy.phpを編集。未ログインユーザーもアクセスできるよう、一部引数に?を付けてnullableな型宣言を行う。

public function viewAny(?User $user) //indexアクションに対応
{
return true; //-- この行を変更
}

public function view(?User $user, Review $review) //showアクションに対応
{
return true; //-- この行を変更
}

public function create(User $user)
{
return true; //-- この行を変更
}

public function update(User $user, Review $review)
{
return $user->id === $review->user_id; //-- この行を変更
}

public function delete(User $user, Review $review)
{
return $user->id === $review->user_id; //-- この行を変更
}

ReviewController.phpに以下を追記。

public function __construct()
{
$this->authorizeResource(Review::class, 'review');
}

詳細画面へアクセスすると、403エラーが表示。ログイン後もエラー。。。

ポリシーでfalseが返されているためshowアクションメソッドが処理されず、403が表示されていると思われる。

モデル名と同じかつappディレクトリ、policiesディレクトリにあれば登録は不要だが、AuthServiceProviderに念のためポリシーを登録。変わらず。

断念して一度@if文を削除して編集ボタンを常に表示する仕様へ。

その他

ログイン画面への追記

どなたでも簡単に利用できるように登録アカウントのメールアドレスとパスワードを明記。

終わりに

今までミドルウェアの実装は済んではいたが、特にポリシーなどの実装は利用してはいなかった。

今回挑戦してみるも、実装できず。

最近学んだことを活かしたブラッシュアップにはならなかった。泣

引き続き改修したらこの記事に追記していくかもしれません。頑張ります。

コメントを残す