【LARAVEL】【ダイエット支援】データ一覧画面からデータ更新

前回までの状況はこちら。

最新ソースはこちら(gitHub)

https://github.com/takishita2nd/diet-mng

データ編集・更新できるようにします。

まず、編集ダイアログのコンポーネントですが、入力のときと別物にしましょう。

同じコンポーネントも使えるかもしれないけど、いろいろめんどくさい。

<template>
    <div>
        <div id="overlay" v-show="show">
            <div id="content">
                <p v-if="error_flg == true" class="error">
                    <ui>
                        <li v-for="error in errors">{{ error }}</li>
                    </ui>
                </p>
                <table class="edit">
                    <tbody>
                        <tr>
                            <td>体重</td>
                            <td><input type="number" v-model="contents.weight" /></td>
                        </tr>
                        <tr>
                            <td>体脂肪</td>
                            <td><input type="number" v-model="contents.fat_rate" /></td>
                        </tr>
                        <tr>
                            <td>BMI</td>
                            <td><input type="number" v-model="contents.bmi" /></td>
                        </tr>
                    </tbody>
                </table>
                <p id="command">
                    <button @click="clickAdd">入力</button>
                    <button @click="closeModal">閉じる</button>
                </p>
            </div>
        </div>
    </div>
</template>
<script>
export default {
    props: ['show'],
    data() {
        return {
            errors: [],
            error_flg: [],
            param: {},
            contents: {
                id: "",
                weight: "",
                fat_rate: "",
                bmi: "",
            },
        };
    },
    created: function() {
    },
    methods: {
        dataSet: function(data) {
            this.contents = data;
        },
        clickAdd: function() {
            var self = this;
            this.param.contents = this.contents;
            axios.post('api/weight/edit', this.param).then(function(response){
                self.clear();
                self.closeModal();
                self.$emit('update');
            }).catch(function(error){
                self.error_flg = true;
                self.errors = error.response.data.errors;
            });
        },
        closeModal: function() {
            this.$parent.showEditDialogContent = false;
        },
        clear: function() {
            this.contents.weight = "";
            this.contents.fat_rate = "";
            this.contents.bmi = "";
            this.error_flg = false;
            this.errors = [];
        }
    }
}
</script>

そして、それを使用する側の親コンポーネント。

        <div>
            <weight-input-dialog-component :show="showInputDialogContent" @update="invokeUpdateList"></weight-input-dialog-component>
            <weight-edit-dialog-component ref="editDialog" :show="showEditDialogContent" @update="invokeUpdateList"></weight-edit-dialog-component>
        </div>
        onClickEdit: function(id) {
            var editData = {};
            this.datalists.forEach(element => {
                if(element.id == id){
                    editData.id = id;
                    editData.weight = element.weight;
                    editData.fat_rate = element.fat_rate;
                    editData.bmi = element.bmi;
                    return true;
                }
            });
            this.$refs.editDialog.dataSet(editData);
            this.showEditDialogContent = true;

ポイントは、編集ダイアログにデータを渡すとき。

親コンポーネントから子コンポーネントのメソッドをコールしています。

これは、子コンポーネントを定義するときに、

ref="editDialog"

と書くことで、

            this.$refs.editDialog.dataSet(editData);

と、子コンポーネントのメソッドを実行できます。

その引数でパラメータを渡して、表示させています。

あとは、今までどおり。

Repository

    public function edit($id, $weight, $fat_rate, $bmi)
    {
        $model = $this->getItemById($id);
        $model->weight = $weight;
        $model->fat_rate = $fat_rate;
        $model->bmi = $bmi;
        $model->save();
    }

    public function getItemById($id)
    {
        return WeightManagement::where(['id' => $id])->first();
    }

controller

    /**
     * データを1件更新する
     */
    public function edit(Request $request)
    {
        $param = $this->weightManagement->getParam();
        $this->weightManagement->edit( $request->contents["id"], 
            $request->contents["weight"],
            $request->contents["fat_rate"],
            $request->contents["bmi"]
        );
        
        return response()->json();
    }
Route::post('api/weight/edit', 'Weight\ApiController@edit');

【ラズパイ】【GLCD】ディスプレイのいろんなところに表示させてみる。

前回までの状況はこちら。

前回でLCDディスプレイの初期化も終わってますし、データを書き込む関数も一通り揃っています。

なので、いろいろ書いてみましょうか。

とはいっても、今の状態では、ドット単位で表示する/しないの設定しかできませんが。

def __main():
    PinsInit(20, 7, 8, 9, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17)
    GLCDInit()
    GLCDDisplayClear()
    SelectIC(1)
    SetPage(0)
    SetAddress(0)
    WriteData(0xFF)
    try:
        while True:
            time.sleep(1.0)
    except KeyboardInterrupt:
        GPIO.cleanup()

ICチップ1番、ページ0、アドレス0に0xFF(全点灯)を設定します。

左上一列が点灯しました。(分かるかな・・・)

ICチップ1番、ページ1、アドレス1に書き込みました。

ICチップ1番、ページ7、アドレス63に書き込みました。

ICチップ2番、ページ0、アドレス0に書き込みました。

ICチップ2番、ページ7、アドレス63に書き込みました。

右下の4ドットは右上に表示するアイコンに対応しています。

なので、LCDを全点灯した場合、右下4ドット分は欠けて見えます。

まぁ、ここまでをまとめると、

こういうことですな。

ここまで分かれば、後はデータさえ用意できれば、いろいろ表示できそうだ。

【LARAVEL】【ダイエット支援】データ一覧画面からデータ入力

前回までの状況はこちら。

最新ソースはこちら(gitHub)

https://github.com/takishita2nd/diet-mng

データ一覧画面からデータ入力を行います。

<template>
    <div>
        <div>
            <p id="navi">> <a href="/home">HOME</a></p>
            <p id="inputbutton">
                <button @click="onClickInput">データ入力</button>
            </p>
            <table class="weightlist">
                <tbody>
                    <tr>
                        <th class="date">日時</th>
                        <th class="weight">体重(kg)</th>
                        <th class="fat_rate">体脂肪(%)</th>
                        <th class="bmi">BMI</th>
                        <th class="edit"></th>
                        <th class="delele"></th>
                    </tr>
                    <tr v-for="data in datalists">
                        <td class="date">{{ data.date}}</td>
                        <td class="weight">{{ data.weight}}</td>
                        <td class="fat_rate">{{ data.fat_rate}}</td>
                        <td class="bmi">{{ data.bmi}}</td>
                        <td class="edit"><a href="">Edit</a></td>
                        <td class="delele"><a href="">Delete</a></td>
                    </tr>
                </tbody>
            </table>
        </div>
        <div>
            <weight-input-dialog-component :show="showDialogContent" @update="invokeUpdateList"></weight-input-dialog-component>
        </div>
    </div>
</template>

入力ダイアログ画面は、すでに作成してあるコンポーネントを流用します。

しかし、この一覧画面から入力した場合は、入力後、リストを更新する必要があります。

なので、入力ダイアログコンポーネントから親コンポーネントで信号を送って、リスト更新処理を走らせるようにします。

入力処理はこんな感じ。

        clickAdd: function() {
            var self = this;
            this.param.contents = this.contents;
            axios.post('api/weight/add', this.param).then(function(response){
                self.clear();
                self.closeModal();
                self.$emit('update');
            }).catch(function(error){
                self.error_flg = true;
                self.errors = error.response.data.errors;
            });
        },

ポイントは、親側(データ一覧画面)側で

<weight-input-dialog-component :show="showDialogContent" @update="invokeUpdateList"></weight-input-dialog-component>

@update=”invokeUpdateList”の部分。

これがある状態で、子コンポーネントから

this.$emit('update');

を実行すると、親コンポーネントのinvokeUpdateList()メソッドが実行されます。

    created: function() {
        this.updateList();
    },
    methods: {
        onClickInput: function() {
            this.showDialogContent = true;
        },
        invokeUpdateList: function() {
            this.updateList();
        },
        updateList: function() {
            this.datalists = [];
            var self = this;
            axios.post('api/weight/list').then(function(response){
                response.data.dataLists.forEach(element => {
                    self.datalists.push({
                        date: element.datetime,
                        weight: element.weight,
                        fat_rate: element.fat_rate,
                        bmi: element.bmi
                    })
                });
            }).catch(function(error){
            });
        }
    }

こんな感じで更新処理を行えばOK。

ちなみに、ダッシュボード画面(:@updateの記載がない)に対して$emit(‘update’)を行っても特にエラーにはなりませんでした。

子コンポーネント定義に書かなければ、emitしても何事もなく動くみたいです。

【C#】【ピクロス】【ALTSEED】簡単な問題は解けるようになりました(たぶん)

前回までの状況はこちら。

最新ソースはこちら。(gitHub)

https://github.com/takishita2nd/Picross

あれから、いくつかの問題を解いてみましたが、まだまだ不具合が多く、調査・修正しながら解いていきました。

どこを直したかはgitHubのコードを参照して頂きたく。

だいたいここまで攻略できれば、解析処理も一段落できそう。

解析処理は一旦ここまでにして、UI側の修正に戻ろうと思います。

いろいろ弄っていると、UIの挙動にもおかしいところが見受けられたので、その修正を行いたいと思います。

【ラズパイ】【GLCD】LCDモジュールを初期化して使用できるようにする

前回までの状況はこちら。

さて、このLCDディスプレイを実際にPythonで動かすのですが。

やっぱり、自分一人の力ではなかなか難しかったので、

こちらのサイトのサンプルソースコードを参考にさせて貰いました。

http://zattouka.net/GarageHouse/micon/Arduino/GLCD/GLCD.htm

こちらはArduinoで使用した物で、ソースコードもC言語に似た独自言語を使用しています。

これをラズパイ/Python用に落とし込みます。

import RPi.GPIO as GPIO
import time

RS_p = 7
RW_p = 8
E_p = 9
CS1_p = 18
CS2_p = 19
DATA_p = [0] * 8
SetPg = 0
SetCol = 0

def PinsInit(rst, rs, rw, enable, cs1, cs2, d0, d1, d2, d3, d4, d5, d6, d7):
    GPIO.setmode(GPIO.BCM)

    #データピンの番号セット
    DATA_p[0] = d0
    DATA_p[1] = d1
    DATA_p[2] = d2
    DATA_p[3] = d3
    DATA_p[4] = d4
    DATA_p[5] = d5
    DATA_p[6] = d6
    DATA_p[7] = d7
    #制御ピンの番号をセット
    RS_p = rs
    RW_p = rw
    E_p = enable
    CS1_p = cs1
    CS2_p = cs2
    #指定の制御ピンをデジタル出力に設定
    GPIO.setup(RS_p, GPIO.OUT)
    GPIO.setup(RW_p, GPIO.OUT)
    GPIO.setup(E_p, GPIO.OUT)
    GPIO.setup(CS1_p, GPIO.OUT)
    GPIO.setup(CS2_p, GPIO.OUT)
    #指定のデータピンをデジタル出力に設定
    for i in range(8):
        GPIO.setup(DATA_p[i], GPIO.OUT)
    #信号線をLOWに設定しておく
    GPIO.output(RS_p, GPIO.LOW)
    GPIO.output(RW_p, GPIO.LOW)
    GPIO.output(E_p, GPIO.LOW)
    GPIO.output(CS1_p, GPIO.LOW)
    GPIO.output(CS2_p, GPIO.LOW)
    #LCDモジュールのリセットを解除する
    GPIO.setup(rst, GPIO.OUT)
    GPIO.output(rst, GPIO.HIGH)

ここでは、ラズパイのGPIOの入出力設定と信号線の対応を行っています。

ちなみに、今のブレッドボードでは以下の様に接続されています。

設定が終わったらRSTの信号をHIGHにすることでLCDディスプレイが使用可能になります。

def GLCDInit():
    #30ms待機
    time.sleep(0.03)
    #左側ICを初期化
    SelectIC(1)
    command(0xC0, GPIO.LOW)
    command(0x3F, GPIO.LOW)
    #左側ICを初期化
    SelectIC(2)
    command(0xC0, GPIO.LOW)
    command(0x3F, GPIO.LOW)

def SelectIC(value):
    if value == 1:
        GPIO.output(CS1_p, GPIO.HIGH)
        GPIO.output(CS2_p, GPIO.LOW)
    else:
        GPIO.output(CS1_p, GPIO.LOW)
        GPIO.output(CS2_p, GPIO.HIGH)

def command(value, mode):
    GPIO.output(RS_p, mode)
    for i in range(8):
        GPIO.output(DATA_p[i], (value >> i) & 0x01)
    GPIO.output(E_p, GPIO.HIGH)
    GPIO.output(E_p, GPIO.LOW)

LCDディスプレイの初期化を行います。

ここでは、マニュアルに書いてあるとおりの手順を行います。

このディスプレイはICチップが2枚使用されていて、SelectIC()でコマンドを送信するICチップの番号を設定します。

command()でコマンドを送信します。

第2パラメータはLOW(制御コマンド)、HIGH(表示データ)を選択します。

(もっとわかりやすくした方が良いな・・・)

あと、サンプルを見て気がついたのは、信号をインプットするのに、E信号をHIGHにしなくちゃいけない、ということ。

HIGHでRSやデータ信号が実際にLCDモジュールに入ります。で、終わったらLOWに戻します。

タイミングチャートにしっかり書いてあった・・・

def GLCDDisplayClear():
    for i in [1, 2]:
        SelectIC(i)
        for y in range(8):
            SetPage(y)
            SetAddress(0)
            for x in range(64):
                WriteData(0)

def SetPage(value):
    command(0xB8|(value&0x07), GPIO.LOW)

def SetAddress(value):
    command(0x40|(value&0x3F), GPIO.LOW)

def WriteData(value):
    command(value, GPIO.HIGH)

ディスプレイの表示を全て非表示に設定します。(画面クリア)

def __main():
    PinsInit(20, 7, 8, 9, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17)
    GLCDInit()
    GLCDDisplayClear()
    try:
        while True:
            time.sleep(1.0)
    except KeyboardInterrupt:
        GPIO.cleanup()

__main()

これで、一通りの初期化処理ができました。

データを書き込む関数もあるから、次回はちょっといろいろ表示させてみようか。

【ラズパイ】【GLCD】半固定抵抗が届いたので、回路に組み込んでみる

前回までの状況はこちら。

半固定抵抗が秋月電子から届きました。

秋月電子ホームページ

回路に設置。

LCDモジュールの18番(Vee)を半固定抵抗の3番(左の端子)に接続、

ラズパイの5Vを半固定抵抗の1番(右の端子)に接続、

LCDモジュールの3番(Vo)を半固定抵抗の2番に接続します。

つまみを回すと、それに応じて2番から出力される電圧が変化し、それがVoに入ると、LCDのコントラストが変化します。

これがコントラストMAXの状態。

何も表示されなかった前回より進展しました。

さぁ、ゴリゴリPythonを書こうか。

【LARAVEL】【ダイエット支援】データ一覧画面を作成する

前回までの状況はこちら。

最新ソースはこちら(gitHub)

https://github.com/takishita2nd/diet-mng

データ一覧画面を作成します。

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">体重管理</div>

                <div class="panel-body">
                    @if (session('status'))
                        <div class="alert alert-success">
                            {{ session('status') }}
                        </div>
                    @endif
                </div>
                <weight-list-component></weight-list-component>
            </div>
        </div>
    </div>
</div>
@endsection

実際に表示するのはVue.jsで作成します。

<template>
    <div>
        <table class="weightlist">
            <tbody>
                <tr>
                    <th class="date">日時</th>
                    <th class="weight">体重(kg)</th>
                    <th class="fat_rate">体脂肪(%)</th>
                    <th class="bmi">BMI</th>
                    <th class="edit"></th>
                    <th class="delele"></th>
                </tr>
                <tr v-for="data in datalists">
                    <td class="date">{{ data.date}}</td>
                    <td class="weight">{{ data.weight}}</td>
                    <td class="fat_rate">{{ data.fat_rate}}</td>
                    <td class="bmi">{{ data.bmi}}</td>
                    <td class="edit"><a href="">Edit</a></td>
                    <td class="delele"><a href="">Delete</a></td>
                </tr>
            </tbody>
        </table>
    </div>
</template>

データ一覧を取得するAPIを作成します。

class WeightManagementRepository
{
    public function list($user)
    {
        return $user->WeightManagements()->get();
    }
}
class ApiController extends Controller
{
    /**
     * データを取得する
     */
    public function list(Request $request)
    {
        return response()->json(['dataLists' => $this->weightManagement->list(Auth::user())]);
    }
Route::post('api/weight/list', 'Weight\ApiController@list');

このAPIを使用してVue.js側からデータの取得を行います。

<script>
export default {
        data() {
        return {
            datalists: [],
        };
    },
    created: function() {
        var self = this;
        axios.post('api/weight/list').then(function(response){
            response.data.dataLists.forEach(element => {
                self.datalists.push({
                    date: element.datetime,
                    weight: element.weight,
                    fat_rate: element.fat_rate,
                    bmi: element.bmi
                })
            });
        }).catch(function(error){
        });
    }
}
</script>
Vue.component('weight-list-component', require('./components/WeightListComponent.vue'));

これで動くはず。

以前、課題で作成したホテル予約管理のコードを参照して作成しました。

こういうの取っておくと便利よね。

【ぼっち】炭火居酒屋炎 福住店

今なら言える。

自粛警察くそくらえ!

札幌市では、非常事態宣言解除を受けて、感染症対策ができた店舗から夜のお店も通常営業に戻りつつあります。

このお店も、昨日から営業再開しました。

外で飲むのは一ヶ月半ぶりかな?

ぼっちに優しいのは、このお店、

タッチパネルで注文できるんです。

この生つくねが食べたかった。

このトング考えた人は天才だと思う。

【C#】【ピクロス】【ALTSEED】いろいろと修正。

前回までの状況はこちら。

最新ソースはこちら。(gitHub)

https://github.com/takishita2nd/Picross

こちらの問題を解いてみました。

もちろん一発で解けるとは思っていませんでした。

しかし、ここまでハマるとは・・・

解析パターン5にバグがあって、

いろいろコードを書き換えながら試行錯誤していったんですが、

結局、コードと格闘すること5時間。

解けました。

大きな変更としては、解析済みの数字に対して、きちんと解析済みフラグを設定しましょう、ということで、

要するに、

縦の数字を埋めていったら、横の数字も出来上がっているにもかかわらず、解析済みフラグが立っていないケースがあって、それで動きがおかしくなっていたので、きちんと解析完了フラグを立てましょう、ということを入れました。

        private void checkAnalyze()
        {
            checkAnalyzeRowBefore();
            checkAnalyzeRowAfter();
            checkAnalyzeColBefore();
            checkAnalyzeColAfter();
        }

        private void checkAnalyzeRowBefore()
        {
            int row = 0;
            foreach (var rowList in rowNumbers)
            {
                if (rowList.IsAnalyzed())
                {
                    row++;
                    continue;
                }

                rowList.AnalyzeDatas.Reverse();
                int rowIndex = 0;
                foreach(var rowData in rowList.AnalyzeDatas)
                {
                    if (rowData.IsAnalyzed())
                    {
                        rowIndex++;
                    }
                    else
                    {
                        break;
                    }
                }
                if (rowIndex == rowList.AnalyzeDatas.Count)
                {
                    rowList.AnalyzeDatas.Reverse();
                    row++;
                    continue;
                }

                int painted = 0;
                int count = 0;
                for (int col = 0; col < colNumbers.Count; col++)
                {
                    if (_bitmapData[row, col].IsPainted())
                    {
                        painted++;
                    }
                    else if (_bitmapData[row, col].IsMasked())
                    {
                        if(count == rowIndex)
                        {
                            if (rowList.AnalyzeDatas[rowIndex].Value == painted)
                            {
                                rowList.AnalyzeDatas[rowIndex].Analyzed();
                                rowList.CheckAnalyze();
                            }
                        }
                        else
                        {
                            count++;
                        }
                    }
                    else
                    {
                        rowList.AnalyzeDatas.Reverse();
                        row++;
                        break;
                    }
                }
            }
        }

        private void checkAnalyzeRowAfter()
        {
            int row = 0;
            foreach (var rowList in rowNumbers)
            {
                if (rowList.IsAnalyzed())
                {
                    row++;
                    continue;
                }

                int rowIndex = 0;
                foreach (var rowData in rowList.AnalyzeDatas)
                {
                    if (rowData.IsAnalyzed())
                    {
                        rowIndex++;
                    }
                    else
                    {
                        break;
                    }
                }
                if(rowIndex == rowList.AnalyzeDatas.Count)
                {
                    row++;
                    continue;
                }

                int painted = 0;
                int count = 0;
                for (int col = colNumbers.Count - 1; col >= 0; col--)
                {
                    if (_bitmapData[row, col].IsPainted())
                    {
                        painted++;
                    }
                    else if (_bitmapData[row, col].IsMasked())
                    {
                        if (count == rowIndex)
                        {
                            if (rowList.AnalyzeDatas[rowIndex].Value == painted)
                            {
                                rowList.AnalyzeDatas[rowIndex].Analyzed();
                                rowList.CheckAnalyze();
                            }
                        }
                        else
                        {
                            count++;
                        }
                    }
                    else
                    {
                        row++;
                        break;
                    }
                }
            }
        }

        private void checkAnalyzeColBefore()
        {
            int col = 0;
            foreach (var colList in colNumbers)
            {
                if (colList.IsAnalyzed())
                {
                    col++;
                    continue;
                }

                colList.AnalyzeDatas.Reverse();
                int colIndex = 0;
                foreach (var colData in colList.AnalyzeDatas)
                {
                    if (colData.IsAnalyzed())
                    {
                        colIndex++;
                    }
                    else
                    {
                        break;
                    }
                }
                if (colIndex == colList.AnalyzeDatas.Count)
                {
                    colList.AnalyzeDatas.Reverse();
                    col++;
                    continue;
                }
                int painted = 0;
                int count = 0;
                for (int row = 0; row < rowNumbers.Count; row++)
                {
                    if (_bitmapData[row, col].IsPainted())
                    {
                        painted++;
                    }
                    else if (_bitmapData[row, col].IsMasked())
                    {
                        if (count == colIndex)
                        {
                            if (colList.AnalyzeDatas[colIndex].Value == painted)
                            {
                                colList.AnalyzeDatas[colIndex].Analyzed();
                                colList.CheckAnalyze();
                            }
                        }
                        else
                        {
                            count++;
                        }
                    }
                    else
                    {
                        colList.AnalyzeDatas.Reverse();
                        col++;
                        break;
                    }
                }
            }
        }

        private void checkAnalyzeColAfter()
        {
            int col = 0;
            foreach (var colList in colNumbers)
            {
                if (colList.IsAnalyzed())
                {
                    col++;
                    continue;
                }

                int colIndex = 0;
                foreach (var colData in colList.AnalyzeDatas)
                {
                    if (colData.IsAnalyzed())
                    {
                        colIndex++;
                    }
                    else
                    {
                        break;
                    }
                }
                if (colIndex == colList.AnalyzeDatas.Count)
                {
                    col++;
                    continue;
                }
                int painted = 0;
                int count = 0;
                for (int row = rowNumbers.Count - 1; row >= 0; row--)
                {
                    if (_bitmapData[row, col].IsPainted())
                    {
                        painted++;
                    }
                    else if (_bitmapData[row, col].IsMasked())
                    {
                        if (count == colIndex)
                        {
                            if (colList.AnalyzeDatas[colIndex].Value == painted)
                            {
                                colList.AnalyzeDatas[colIndex].Analyzed();
                                colList.CheckAnalyze();
                            }
                        }
                        else
                        {
                            count++;
                        }
                    }
                    else
                    {
                        col++;
                        break;
                    }
                }
            }
        }

細かい所は、直接gitHubのコードを見て欲しく。

何より大変だったのは、既存部分を変更することにより、過去の問題が解けなくなる可能性もあり、その確認のため、過去問を引っ張り出してきたこと。

セーブ&ロード機能実装してて正解だったわ。

無かったら確実に発狂してる。

とはいえ、この作業に大半の時間を使ってしまったので、他の作業ができなかったので、今日は他の作業に取りかかろう。

【Laravel】【ダイエット支援】クイック入力処理の実装

前回の状況はこちら。

最新ソースはこちら

https://github.com/takishita2nd/diet-mng

さて、前回作成したダイアログから入力したデータをサーバ側に送って、データベースに保存します。

まずはPHP側から。

WebAPIを作成します。

class ApiController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
        $this->weightManagement = new WeightManagementRepository();
    }

    public function add(Request $request)
    {
        $param = $this->weightManagement->getParam();
        $this->weightManagement->add([
            $param[0] => date('Y-m-d H:i'),
            $param[1] => $request->contents["weight"],
            $param[2] => $request->contents["fat_rate"],
            $param[3] => $request->contents["bmi"],
        ], Auth::user());
        
        return response()->json();
    }
}
class WeightManagementRepository
{
    private $paramNames = ['datetime', 'weight', 'fat_rate', 'bmi'];

    public function __construct()
    {

    }

    public function add($param, $user)
    {
        $model = new WeightManagement();
        foreach($this->paramNames as $name)
        {
            $model->$name = $param[$name];
        }
        $model->save();
        $this->attachToUser($model, $user);
    }

    public function attachToUser($model, $user)
    {
        $model->users()->attach($user);
    }

    public function getParam()
    {
        return $this->paramNames;
    }
}
class WeightManagement extends Model
{
    public function users()
    {
        return $this->belongsToMany('App\User');
    }
}
class User extends Authenticatable
{

    public function WeightManagements()
    {
        return $this->belongsToMany('App\Model\WeightManagement');
    }

}
Route::post('api/weight/add', 'Weight\ApiController@add');

これでAPIが完成。

次はVue.js側です。

<template>
    <div>
        <div id="overlay" v-show="show">
            <div id="content">
                <p v-if="error_flg == true" class="error">
                    <ui>
                        <li v-for="error in errors">{{ error }}</li>
                    </ui>
                </p>
                <table class="edit">
                    <tbody>
                        <tr>
                            <td>体重</td>
                            <td><input type="number" v-model="contents.weight" /></td>
                        </tr>
                        <tr>
                            <td>体脂肪</td>
                            <td><input type="number" v-model="contents.fat_rate" /></td>
                        </tr>
                        <tr>
                            <td>BMI</td>
                            <td><input type="number" v-model="contents.bmi" /></td>
                        </tr>
                    </tbody>
                </table>
                <p id="command">
                    <button @click="clickAdd">入力</button>
                    <button @click="closeModal">閉じる</button>
                </p>
            </div>
        </div>
    </div>
</template>
<script>
export default {
    props: ['show'],
    data() {
        return {
            errors: [],
            error_flg: [],
            param: {},
            contents: {
                weight: "",
                fat_rate: "",
                bmi: "",
            },
        };
    },
    created: function() {
    },
    methods: {
        clickAdd: function() {
            var self = this;
            this.param.contents = this.contents;
            axios.post('api/weight/add', this.param).then(function(response){
                self.clear();
                self.closeModal();
            }).catch(function(error){
                self.error_flg = true;
                self.errors = error.response.data.errors;
            });
        },
        closeModal: function() {
            this.$parent.showDialogContent = false;
        },
        clear: function() {
            this.contents.weight = "";
            this.contents.fat_rate = "";
            this.contents.bmi = "";
            this.error_flg = false;
            this.errors = [];
        }
    }
}
</script>

contentsの各パラメータが入力ダイアログのinputの値と結びついています。

入力ボタンをクリックすると、contetsをparamに設定し、app/weight/addへPOSTリクエストを送信します。

応答が帰ってくると、ダイアログを閉じます。

うまくいっているようです。

自分、ぼっちですが何か?