1
1

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】リレーション関係にある親モデルのIDを子モデルに登録したい

Last updated at Posted at 2022-12-20

リレーション関係にある親モデルのIDを子モデルに登録する

user_idなどの場合、

$hoge->user_id = Auth::id();

な感じでリレーションが効いて、フォームに自動で登録がされますが、
他テーブルの場合そうもいかないため苦戦しました。

今回やりたかったこと

ideal_weightという親テーブルとuser_motivationという子テーブルがあり、
1:1の関係を持っています。

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 function user() {
        return $this->belongsTo(User::class);
    }

    public function userMotivation() {
        return $this->hasOne(UserMotivation::class);
    }
}


class UserMotivation extends Model
{
    use HasFactory;
    protected $fillable = ['training_frequency','purpose'];

    public function user() {
        return $this->belongsTo(User::class);
    }

    public function idealWeight() {
        return $this->belongsTo(IdealWeight::class);
    }
}

テーブル構成はこんな感じです。
↓親テーブル
スクリーンショット 2022-12-20 17.01.55.png

↓子テーブル
スクリーンショット 2022-12-20 17.03.40.png

子テーブルであるuser_motivationにてフォーム登録する際、
この紐付いているideal_weight_iduser_idのように自動で登録したいと考えました。

うまくいかない

Railsだとすごく簡単にできた気がするのですが、
なかなかうまくできず大苦戦してました。

①userMotivationをnewして、それをもとにidへアクセスすればいけるかと思い、
下記コードで書きましたが、NULLが登録されてしまいました。

    public function create()
    {
        $user_id = Auth::id();
        if (userMotivation::where('user_id', $user_id)->exists()) {
            return redirect()->route('usermotivations.index')->with(
                'message', 'ボディメイク目標は既に登録済みです'
            );
        }
        return view('usermotivations.create');
    }
    public function store(UserMotivationRequest $request)
    {
        $validated = $request->safe()->only([
            'training_frequency',
            'purpose',
        ]);

        $userMotivation = new userMotivation();
        $idealWeight = new idealWeight();

        // バリデーション
        $userMotivation->training_frequency = $validated['training_frequency'];
        $userMotivation->purpose = $validated['purpose'];

        $userMotivation->user_id = Auth::id();
        $userMotivation->ideal_weight_id = $idealWeight->id;

        $userMotivation->save();

        return redirect()->route('usermotivations.index')->with(
            'message', '登録が完了しました'
        );
    }

②storeメソッドにおいて、idを引数として、
IdealWeight::find($id)と記載してみましたが、引数が少ないとエラーを吐いてしまい、
このやり方も違うと考えました。
Too few arguments to function App\Http\Controllers\UserMotivationController::store(), 1 passed in /work/backend/vendor/laravel/framework/src/Illuminate/Routing/Controller.php on line 54 and exactly 2 expected

    public function store(UserMotivationRequest $request, $id)
    {
        $validated = $request->safe()->only([
            'training_frequency',
            'purpose',
        ]);

        $userMotivation = new userMotivation();

        // バリデーション
        $userMotivation->training_frequency = $validated['training_frequency'];
        $userMotivation->purpose = $validated['purpose'];

        $userMotivation->user_id = Auth::id();
        $userMotivation->ideal_weight_id = IdealWeight::find($id);

        $userMotivation->save();

        return redirect()->route('usermotivations.index')->with(
            'message', '登録が完了しました'
        );
    }

解決したコード

storeメソッドにて、
ideal_weight_idを登録する際に、where句を使って探し出してくればよかったようです!

$userMotivation->ideal_weight_id = IdealWeight::where('user_id', '=', Auth::id())->first()->id;

これで登録されました\(^o^)/

念の為tinkerでも見てみます。

>>> IdealWeight::where('user_id', 3)->first()->id;
=> 2

今回も勉強になりました(^^)

1
1
3

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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?