1
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?

More than 1 year has passed since last update.

【Laravel9】入力したカラムを使って別カラムに値を入れる

Last updated at Posted at 2022-12-22

ユーザーが入力したカラムを使って、同テーブルの別カラムに値を入れたい

Railsを書いていた頃は、モデルにbefore_saveメソッドを書いて
そこに計算式などを書いていたのだが、Laravelの場合どのように書くとやりたいことができるのか??

例えば、ユーザーがheightweightを入力したとして、
その値をシステムが計算し、basemetabolismというカラムに値を自動で入れてくれる場合、
Railsだと下記のようにモデルに記載することで実装できる。
(そもそもこれがベストプラクティスかはわからない)

before_save do
    self.basemetabolism = 13.397*(weight)+4.799*(height)-5.677*(user.age)+88.362
end

同様のやり方でLaravelでもできないかなと思ったのですが、
いまいちしっくりこなかったので、一次避難としてコントローラに直接計算式を書いてしまうことにしました。

実際のコード(Laravel)

public function store(IdealWeightRequest $request) {
    $idealWeight = new IdealWeight();
    $idealWeight->basal_metabolism = 13.397*($idealWeight->weight)+4.799*($idealWeight->height)-5.677*(Auth::user()->age)+88.362;
}

カラムが1つだけならまだいいですが、
多くなってくるとコントローラの可読性が下がるため他にいい方法ないかなと思っています。
一旦問題なく動いてはいるので最優先ではないですが、
なにか良い方法がありましたらコメントいただけますと助かりますm(_ _)m

追記

モデルに以下を記載し、fillableを使ってまとめてコントローラでsaveをすることで
コントローラの記述をスッキリさせることができました!
@sgrs38 さんアドバイスありがとうございます!

IdealWeightController

public function store(IdealWeightRequest $request) {

        $validated = $request->safe()->only([
            'height',
            'weight',
            'target_weight',
            'exercise_level',
            'start_day',
            'last_day',
        ]);

        $idealWeight = new IdealWeight();

        $idealWeight->user_id = Auth::id();
        $idealWeight->fill($request->all())->save();

        return redirect()->route('idealweights.index')->with(
            'message', '基本情報の入力が完了したので、次に目標を登録しましょう'
        );
    }

IdealWeight.php

class IdealWeight extends Model
{
    use HasFactory;
    protected $fillable = ['height','weight','target_weight', 'exercise_level', 'period', 'basal_metabolism', 'calories_burned', 'minus_weight', 'minus_calories', 'calories_intake', 'protein_gram_intake', 'protein_calories_intake', 'fat_gram_intake', 'fat_calories_intake', 'carbo_gram_intake', 'carbo_calories_intake', 'start_day', 'last_day', 'minus_weight_day'];

    public static function boot()
    {
        parent::boot();
        self::saving(function (IdealWeight $idealWeight) {
            // ボディメイク期間
            $idealWeight->period = Carbon::create($idealWeight->last_day)->diffInDays(Carbon::create($idealWeight->start_day));
            // 基礎代謝
            if (Auth::user()->gender === "男") {
                $idealWeight->basal_metabolism = 13.397*($idealWeight->weight)+4.799*($idealWeight->height)-5.677*(Auth::user()->age)+88.362; #男性の場合
            } else {
                $idealWeight->basal_metabolism = 9.247*($idealWeight->weight)+3.098*($idealWeight->height)-4.33*(Auth::user()->age)+447.593; #女性の場合
            }
            // 消費カロリー
            $idealWeight->calories_burned = ($idealWeight->basal_metabolism)*($idealWeight->exercise_level);
            // 何キロ落とすか
            $idealWeight->minus_weight = ($idealWeight->weight)-($idealWeight->target_weight);
            // 何キロカロリー落とすか
            $idealWeight->minus_calories = ($idealWeight->minus_weight)*7200;
            // 1日あたり何キロ落とせば良いか
            $idealWeight->minus_weight_day = ($idealWeight->minus_weight)/($idealWeight->period);
            // 1日あたり何キロカロリー摂取すればいいか
            $idealWeight->calories_intake = ($idealWeight->calories_burned)-($idealWeight->minus_calories)/($idealWeight->period);
            // タンパク質摂取量(g)
            if ($idealWeight->exercise_level === '1.9') {
                $idealWeight->protein_gram_intake = ($idealWeight->weight) * 2;
            } elseif ($idealWeight->exercise_level === '1.73') {
                $idealWeight->protein_gram_intake = ($idealWeight->weight) * 1.8;
            } elseif ($idealWeight->exercise_level === '1.55') {
                $idealWeight->protein_gram_intake = ($idealWeight->weight) * 1.4;
            } elseif ($idealWeight->exercise_level === '1.38') {
                $idealWeight->protein_gram_intake = ($idealWeight->weight) * 1;
            } elseif ($idealWeight->exercise_level === '1.2') {
                $idealWeight->protein_gram_intake = ($idealWeight->weight) * 0.8;
            }
            // タンパク質摂取カロリー(g*4g)
            $idealWeight->protein_calories_intake = ($idealWeight->protein_gram_intake)*4;
            // 脂質摂取カロリー
            $idealWeight->fat_calories_intake = ($idealWeight->calories_intake)*0.2;
            // 脂質摂取量(g)
            $idealWeight->fat_gram_intake = ($idealWeight->fat_calories_intake)/9;
            // 炭水化物摂取カロリー
            $idealWeight->carbo_calories_intake = ($idealWeight->calories_intake)-($idealWeight->protein_calories_intake)-($idealWeight->fat_calories_intake);
            // 炭水化物摂取量(g)
            $idealWeight->carbo_gram_intake = ($idealWeight->carbo_calories_intake)/4;
        });
    }
}

実はこんなに長かったカラム間で計算したい記述。。
これがベストプラクティスかは再度わからないですが、コントローラがスッキリしたので
以前よりはかなり可読性もあがってよかったですm(_ _)m

1
0
2

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
1
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?