前回までの状況はこちら。
最新ソースはこちら(gitHub)
https://github.com/takishita2nd/diet-mng
今回はデータ一覧画面を作成していきます。
この画面は日付ごとにタンパク質、脂質、炭水化物、カロリーを集計して一覧表示にします。
今回の一番の肝、データを処理するリポジトリの処理。
class EatingManagementRepository
{
private $paramNames = ['date', 'item', 'protein', 'liqid', 'carbo', 'calorie'];
/**
* データを取得して日毎にまとめる
*/
public function getDailyList($user, $page = 1, $days = 10)
{
$dates = [];
for($i = ($page - 1); $i < ($days * $page) ; $i++) {
$dates[] = date('Y-m-d', strtotime('today - '.$i.' day'));
}
$eatings = $user->EatingManagements()
->whereIn(DB::raw('date_format(date, "%Y-%m-%d")'), $dates)
->get();
// 日毎に集計
$dailyDatas = [];
foreach($eatings as $eating) {
for($j = 2; $j < count($this->paramNames); $j++) {
if(!array_key_exists($eating->date, $dailyDatas)) {
$dailyDatas[$eating->date] = [];
}
if(!array_key_exists($this->paramNames[$j], $dailyDatas[$eating->date])) {
$dailyDatas[$eating->date][$this->paramNames[$j]] = 0;
}
$dailyDatas[$eating->date][$this->paramNames[$j]] += $eating->{$this->paramNames[$j]};
}
}
// 戻り値に変換
$retDatas = [];
$index = 0;
foreach($dailyDatas as $dailykey => $dailyData) {
$retDatas[$index][$this->paramNames[0]] = $dailykey;
for($k = 2; $k < count($this->paramNames); $k++) {
$retDatas[$index][$this->paramNames[$k]] = $dailyDatas[$dailykey][$this->paramNames[$k]];
}
}
return $retDatas;
}
まずはwhere inで日付指定でデータを取得するために、今日から(デフォルト)10日前までの日付を配列$datesに作成します。
>>> $dates
=> [
"2020-07-30",
"2020-07-29",
"2020-07-28",
"2020-07-27",
"2020-07-26",
"2020-07-25",
"2020-07-24",
"2020-07-23",
"2020-07-22",
"2020-07-21",
]
そして、DBにアクセスして、データを取得、結果が$eatingsに入ります。
>>> $eatings = $user->EatingManagements()->whereIn(DB::raw('date_format(date, "%Y-%m-%d")'), $dates)->get();=> Illuminate\Database\Eloquent\Collection {#3920 all: [
App\Model\EatingManagement {#3917
id: 1,
date: "2020-07-30",
item: "item1",
protein: 10,
liqid: 10,
carbo: 10,
calorie: 10,
created_at: "2020-07-30 10:38:50",
updated_at: "2020-07-30 10:38:50",
pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3916
user_id: 1,
eating_management_id: 1,
},
},
App\Model\EatingManagement {#3652
id: 2,
date: "2020-07-30",
item: "item2",
protein: 20,
liqid: 20,
carbo: 20,
calorie: 20,
created_at: "2020-07-30 10:39:00",
updated_at: "2020-07-30 10:39:00",
pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3915
user_id: 1,
eating_management_id: 2,
},
},
],
}
このデータを日付毎に集計します。
$dailyDatasは二次元の連想配列になっていて、$dailyDatas[日付][栄養素]という感じで格納されます。
栄養素の連想配列名は定義済みの$paramNamesの値をそのまま使用します。
こうすることで、今後何かDBに修正が入ったとしても、$paramNamesのみを修正すれば良いことになります。
>>> $dailyDatas
=> [
"2020-07-30" => [
"protein" => 30,
"riqid" => 0,
"carbo" => 30,
"calorie" => 30,
],
]
ただ、このままだと、Json化してJavascript側で処理するのに、ものすごい面倒なことになるので、扱いやすいようにデータを変換します。
具体的には、$retDatas[データ番号][項目]という形にします。
>>> $retDatas
=> [
[
"date" => "2020-07-30",
"protein" => 30,
"riqid" => 0,
"carbo" => 30,
"calorie" => 30,
],
]
この状態でJson化してフロントエンド側に送信します。
この処理書くの大変だったわ。
namespace App\Http\Controllers\Eating;
class ApiController extends Controller
{
/**
* データ一覧を取得する
*/
public function list(Request $request)
{
return response()->json(['dataLists' => $this->eatingManagement->getDailyList(Auth::user(), $request->contents["page"])]);
}
Route::post('api/eating/list', 'Eating\ApiController@list');
<script>
export default {
created: function() {
this.updateList();
//this.createPagenate();
},
methods: {
updateList: function() {
this.datalists = [];
this.contents.page = this.currentPage;
this.param.contents = this.contents;
var self = this;
axios.post('api/eating/list', this.param).then(function(response){
response.data.dataLists.forEach(element => {
self.datalists.push({
date: element.date,
protein: element.protein,
liqid: element.liqid,
carbo: element.carbo,
calorie: element.calorie
})
});
}).catch(function(error){
});
}
いやー未だにPHP慣れないわー。
「【ダイエット支援】【食事管理】データ一覧処理を作成する。」への1件のフィードバック