はじめに
よくある口コミの評価(スター)を実装しました。
評価については5段階評価となっています。
動作環境・使用するツールや言語
- OS バージョン
- Windows11
- ツール
- VSCode
- 言語
- HTML&CSS
- フレームワーク
- Laravel8
- スター
- fontawesome v6.4.2
前提
- Laravelのセットアップは済んでいるものとする
- 例なので、簡単な構造での記事(中間テーブルなどは無し)
- DBは数字(
1~5
)の形で挿入される。
先に完成形
- スターが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();
});
}
-
unsignedTinyInteger
で0~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
に修正すると、期待通りの動作になりました。
いやーこんなところで、、、お恥ずかしい。
最近はあまり意識できていなかったせいか、初めてここで時間を使いました。
まあ今後気を付けていきましょ