0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Laravel】満足度評価のためのスター評価フォームの実装

Posted at

はじめに

よくある口コミの評価(スター)を実装しました。
評価については5段階評価となっています。

動作環境・使用するツールや言語

  • OS バージョン
    • Windows11
  • ツール
    • VSCode
  • 言語
    • HTML&CSS
  • フレームワーク
    • Laravel8
  • スター
    • fontawesome v6.4.2

前提

  • Laravelのセットアップは済んでいるものとする
  • 例なので、簡単な構造での記事(中間テーブルなどは無し)
  • DBは数字(1~5)の形で挿入される。

先に完成形

image.png

  • スターが5つ並んでいて、一番左が1、右に大きくなるにつれ数字が上がり、一番右は5。
  • ホバーすると色が変わる。
    例えば、「3」にホバーすると、1、2、3の色が変わる仕様。
  • クリック時にも当然色が変わる。

マイグレーションファイルとモデル

create_ratings_table.php
public function up()
{
    Schema::create('ratings', function (Blueprint $table) {
        $table->id();
        $table->unsignedTinyInteger('rating')->default(0)->nullable(false);
        $table->timestamps();
    });
}
  • unsignedTinyInteger0~255と限られた範囲での使用(今回使うのは0~5)
  • unsignedで負の値NG
  • default(0)でデフォルトを0に設定。1~5だとバグの判別難しいため
  • nullable(false)でnullはもちろん許容しない

フォームリクエスト

RatingRequest.php
public function rules()
{
    return [
        'rating' => 'required|integer|min:1|max:5',
    ];
}

public function messages()
{
    return [
        'rating.required' => '評価は必須項目です',
        'rating.integer' => '評価は整数を指定してください',
        'rating.min' => '評価には1以上の数値を指定してください',
        'rating.max' => '評価には5以下の数値を指定してください',
    ];
}
  • 入力必須、整数、1~5のみ許容

ルーティング

web.php
Route::get('/', [RatingController::class, 'index'])->name('test');
Route::post('/store', [RatingController::class, 'store'])->name('store');

ビュー(HTML&CSS)

test.blade.php
<form action="{{ route('store') }}" class="form" method="post">
    @csrf
    <p class="form-title">満足度</p>
    <div class="form-rating">
        <input class="form-rating__input" id="star5" name="rating" type="radio" value="5">
        <label class="form-rating__label" for="star5"><i class="fa-solid fa-star"></i></label>

        <input class="form-rating__input" id="star4" name="rating" type="radio" value="4">
        <label class="form-rating__label" for="star4"><i class="fa-solid fa-star"></i></label>

        <input class="form-rating__input" id="star3" name="rating" type="radio" value="3">
        <label class="form-rating__label" for="star3"><i class="fa-solid fa-star"></i></label>

        <input class="form-rating__input" id="star2" name="rating" type="radio" value="2">
        <label class="form-rating__label" for="star2"><i class="fa-solid fa-star"></i></label>

        <input class="form-rating__input" id="star1" name="rating" type="radio" value="1">
        <label class="form-rating__label" for="star1"><i class="fa-solid fa-star"></i></label>
    </div>
    @error('rating')
    <p class="error">{{ $message }}</p>
    @enderror
    <button type="submit">送信</button>
</form>
test.css
.form-rating {
    align-items: center;
    display: flex;
    flex-direction: row-reverse;
    justify-content:flex-end;
    margin-bottom: 20px;
}
.form-rating__input {
    display: none;
}
.form-rating__label {
    color: #ccc;
    cursor: pointer;
    font-size: 24px;
    padding: 0 10px;
    position: relative;
    transition: color 0.3s;
}
.form-rating__label:hover,
.form-rating__label:hover ~ .form-rating__label,
.form-rating__input:checked ~ .form-rating__label {
    /* 「~」でホバー時を動的に、チェック時にそれ以下の数字をもつスターの色も変化 */
    color: #c4c403;
}
.error {
    color: #ff6200;;
}

コントローラー

RatingController
public function index()
{
    return view('test');
}

public function store(RatingRequest $request)
{
    $rating = $request->input('rating');
    $reviewData = [
        'rating' => $rating,
    ];
    Rating::create($reviewData);

    return redirect()->route('test');
}

主要なつまずいた所

1.送信ボタンを押すと、/storeで「403 | THIS ACTION IS UNAUTHORIZED.」が出現。

  • 「このアクションは許可されていません。」とのこと。

考えたこと・実行したこと

  • 素直に捉えて、ファイル権限がない?
    • sudo chmod -R 777 src/*を実行するも解決せず。
  • /storeでエラーが発生しているため、ルートは問題ない。
  • return redirect()->route('test');か?問題ない。
  • そもそもフォームは送れているのか?
    • dd($request);するも、変わらず403エラー。
  • フォームリクエストか?
    • 解決

解決方法

RatingRequest.php
public function authorize()
{
    return false;
}

単純に、falseを返していたことが原因でした。
trueに修正すると、期待通りの動作になりました。

いやーこんなところで、、、お恥ずかしい。
最近はあまり意識できていなかったせいか、初めてここで時間を使いました。
まあ今後気を付けていきましょ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?