経緯
ユーザーが入力した情報以外をDBに登録したり、
ユーザーが入力した情報を加工してDBに登録したりしたい時にはリクエストを上書きする方法があります
多分、ユーザーが入力した情報を加工することは、バグを生む原因になるのでよくないと思いますが、、
今回はその方法を解説していきます
他にはmerge
やinput hidden
とセッションを用いるなど様々な方法があると思います。
参考:
https://qiita.com/Fell/items/52be15196099f83ecdc7
以前作成した給与計算の例でみていきましょう
概要
まず給与計算には従業員名と、年月日、出勤時間、退勤時間、調整金額の入力する欄があるとします
追加画面のコード
add.blade.php
@extends('layouts.app')
//ここはPWA化するためのセクション
@section('header')
<link rel="manifest" href="../../../../manifest.json">
<script>
window.addEventListener('load', function() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register("../../../../serviceWorker.js");
}
});
</script>
@endsection
@section('content')
<div align='right'>
最終更新日{{ $now }}
</div>
<div align='center'>
<h4>勤怠入力はこちらから</h4>
{!! Form::open(['method' => 'post', 'route' => 'dailyPayment.add']) !!}
{{ Form::select('employee_id', ['従業員名' => $employee_option]) }}
<br>
{{ Form::selectYear('year', config('common.this_year') - 1, config('common.this_year'), config('common.this_year')) }}年
//入力するのが営業終わりで昨日の日付分を入力するため、昨日の日付が先月末だった場合は月を先月まで戻す
@if ($lastDay == $yesterday)
{{ Form::selectRange('month', 1, 12, $lastMonth) }}月
@else
{{ Form::selectRange('month', 1, 12, date('n')) }}月
@endif
{{ Form::select('day', config('common.day'), $yesterday) }}日
<br>
出勤時間
{{ Form::select('timeFrom', config('common.work_time'), config('common.timeFrom_default')) }}
退勤時間
{{ Form::select('timeTo', config('common.work_time'), config('common.timeTo_default')) }}
<br>
調整金額
{{ Form::number('adjustment', 0) }}
<br>
{{ Form::submit('追加する') }}
{{ Form::close() }}
</div>
<hr>
@endsection
ここでは時刻をH:i
としていますが、データベースに保存したいのはHi
の時間でした。
そっちの方が給与の計算も時刻の計算も楽なので!
また時間の差分を.0
か.5
で求めるようにしています
そこで以下のようにRequestデータを加工して、上書きすることで、書式を変更して保存することができます
dailyPaymentController.php
public function store(StoreRequest $request)
{
$employee_id = $request->employee_id;
$employee = $this->employee->findOrFail($employee_id);
//勤怠情報の重複をチェック
$exists_record = $this->dailyPayment->where('employee_id', $employee->id)->where('year', $request->year)->where('month', $request->month)->where('day', $request->day)->exists();
//重複していた場合は削除ができる従業員のディテールページにリダイレクト
if ($exists_record) redirect()->route('employee.detail', $employee->id)->with('error', $request->year . '年' . $request->month . '月' . $request->day . '日 ' . $employee->name . "の出勤情報は登録済みです\n削除してからお試しください");
//ここでは:をとりのぞして文字列にしています
$time_from = str_replace(':', '', $request->timeFrom);
$time_to = str_replace(':', '', $request->timeTo);
//ここで文字列として出勤時間と退勤時間を比較する
if ($time_from > $time_to) return redirect()->back()>with('error', '不正な入力です');
//22:00以降の出勤 つまり通常時間がない
$normal_time = 0;
$night_time = 0;
if ($time_from >= '2201') {
$night_time = $time_to - $time_from;
//22:00以降を含む退勤
} elseif ($time_to >= '2201') {
$normal_time = 2200 - $time_from;
$night_time = $time_to - 2200;
//22:00以降の出勤も退勤も含まないので深夜料金がない
} else {
$normal_time = $time_to - $time_from;
}
//通常時間の端数が30の時、30を消して.5に変える
if (preg_match('/30$/', $normal_time) || preg_match('/70$/', $normal_time)) {
$normal_time = ($normal_time == 30) ? '0.5' : substr($normal_time, 0, -2) . '.5';
//通常時間の端数が00の時、00を消して.0に変える
} elseif (preg_match('/00$/', $normal_time)) {
$normal_time = substr($normal_time, 0, -2) . '.0';
}
//深夜時間の端数が30の時、30を消して.5に変える
if (preg_match('/30$/', $night_time) || preg_match('/70$/', $night_time)) {
$night_time = ($night_time == 30) ? '0.5' : substr($night_time, 0, -2) . '.5';
//深夜時間の端数が00の時、00を消して.0に変える
} elseif (preg_match('/00$/', $night_time)) {
$night_time = substr($night_time, 0, -2);
}
$day_total = $normal_time + $night_time * 1.25;
/* NGコード
$request->normal_time = $normal_time;
$request->night_time = $night_time;
$request->day_total = $day_total;
$this->dailyPayment->fill($request->all())->save();
*/
$this->dailyPayment->employee_id = $employee_id;
$this->dailyPayment->year = $request->year;
$this->dailyPayment->month = $request->month;
$this->dailyPayment->day = $request->day;
$this->dailyPayment->time_from = $request->time_from;
$this->dailyPayment->time_to = $request->time_to;
$this->dailyPayment->normal_time = $normal_time;
$this->dailyPayment->night_time = $night_time;
$this->dailyPayment->adjustment = $request->adjustment;
$this->dailyPayment->day_total = $day_total;
$this->dailyPayment->save();
return redirect(route('employee.index'))->with('success', $employee->name . 'の勤怠情報を登録しました');
}
このようにユーザーが入力したデータ以外も直接挿入することができる
たとえば、$this->dailyPayment->employee_id
を1
にすれば、全員の労働が一人のものとなる
なお、コメントアウトに書いている通り
$request->normal_time = $normal_time;
$request->night_time = $night_time;
$request->day_total = $day_total;
$this->dailyPayment->fill($request->all())->save();
$request->all()
を使うことはできない。
注意
この画面はadmin側のみ操作可能です
また、8時間以上働いた場合の増加分は計算しない仕様です。