リレーション関係にある親モデルの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);
}
}
子テーブルであるuser_motivation
にてフォーム登録する際、
この紐付いているideal_weight_id
をuser_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
今回も勉強になりました(^^)