Laravelの勉強中でリレーションの処理で詰まっています。
やりたいこと
フォームから入力した値をもとに、drills、problems、categoriesの各テーブルを更新したい。
初回登録(create)は行えるのですが、同じ内容を更新(update)する場合に、どのように処理を書けばよいか分かりません。
createと同じ処理では単純にレコードが追加になってしまうため、更新対象とするレコードを指定する必要があるのだとは思うのですが・・・。
DB
- usersテーブルとdrillsテーブルは1対多
- drillsテーブルとproblemsテーブルは1対多
- drillsテーブルとcategoriesテーブルは1対1
で紐付いています。
DB
1users 2+-------------+---------------------+------+-----+---------+----------------+ 3| Field | Type | Null | Key | Default | Extra | 4+-------------+---------------------+------+-----+---------+----------------+ 5| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment | 6| description | varchar(255) | NO | | NULL | | 7| drill_id | bigint(20) unsigned | YES | MUL | NULL | | 8| created_at | timestamp | YES | | NULL | | 9| updated_at | timestamp | YES | | NULL | | 10+-------------+---------------------+------+-----+---------+----------------+ 11 12drills 13+------------+---------------------+------+-----+---------+----------------+ 14| Field | Type | Null | Key | Default | Extra | 15+------------+---------------------+------+-----+---------+----------------+ 16| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment | 17| title | varchar(255) | NO | | NULL | | 18| created_at | timestamp | YES | | NULL | | 19| updated_at | timestamp | YES | | NULL | | 20| user_id | bigint(20) unsigned | NO | MUL | NULL | | 21+------------+---------------------+------+-----+---------+----------------+ 22 23problems 24+-------------+---------------------+------+-----+---------+----------------+ 25| Field | Type | Null | Key | Default | Extra | 26+-------------+---------------------+------+-----+---------+----------------+ 27| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment | 28| description | varchar(255) | NO | | NULL | | 29| drill_id | bigint(20) unsigned | YES | MUL | NULL | | 30| created_at | timestamp | YES | | NULL | | 31| updated_at | timestamp | YES | | NULL | | 32+-------------+---------------------+------+-----+---------+----------------+ 33 34categories 35+-------------+---------------------+------+-----+---------+----------------+ 36| Field | Type | Null | Key | Default | Extra | 37+-------------+---------------------+------+-----+---------+----------------+ 38| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment | 39| description | varchar(255) | NO | | NULL | | 40| drill_id | bigint(20) unsigned | YES | MUL | NULL | | 41| created_at | timestamp | YES | | NULL | | 42| updated_at | timestamp | YES | | NULL | | 43+-------------+---------------------+------+-----+---------+----------------+
モデル
php
1<?php 2 3namespace App; 4 5use Illuminate\Contracts\Auth\MustVerifyEmail; 6use Illuminate\Foundation\Auth\User as Authenticatable; 7use Illuminate\Notifications\Notifiable; 8use Illuminate\Database\Eloquent\Relations; 9 10class User extends Authenticatable 11{ 12 use Notifiable; 13 14 protected $fillable = [ 15 'name', 'email', 'password', 16 ]; 17 18 protected $hidden = [ 19 'password', 'remember_token', 20 ]; 21 22 protected $casts = [ 23 'email_verified_at' => 'datetime', 24 ]; 25 26 public function drills() 27 { 28 return $this->hasMany('App\Drill'); 29 } 30 31 public function problems() 32 { 33 return $this->hasManyThrough('App\Problem', 'App\Drill'); 34 } 35 36 public function category() 37 { 38 return $this->hasOneThrough('App\Category', 'App\Drill'); 39 } 40} 41
php
1<?php 2 3namespace App; 4 5use Illuminate\Database\Eloquent\Model; 6 7class Drill extends Model 8{ 9 10 protected $guarded = ['id']; 11 12 public function user() 13 { 14 return $this->belongsTo('App\User'); 15 } 16 17 public function problems() 18 { 19 return $this->hasMany('App\Problem'); 20 } 21 22 public function category() 23 { 24 return $this->hasOne('App\Category'); 25 } 26} 27
php
1<?php 2 3namespace App; 4 5use Illuminate\Database\Eloquent\Model; 6 7class Problem extends Model 8{ 9 protected $guarded = ['id']; 10 11 public function Drill() 12 { 13 return $this->belongsTo('App\Drill'); 14 } 15}
php
1<?php 2 3namespace App; 4 5use Illuminate\Database\Eloquent\Model; 6 7class Category extends Model 8{ 9 protected $guarded = ['id']; 10 11 public function Drill() 12 { 13 return $this->belongsTo('App\Drill'); 14 } 15} 16
コントローラ
php
1?php 2 3namespace App\Http\Controllers; 4 5use App\Category; 6use App\Problem; 7use Illuminate\Http\Request; 8use App\Drill; 9use Illuminate\Support\Facades\App; 10use Illuminate\Support\Facades\Auth; 11 12class DrillsController extends Controller 13{ 14 public function create(Request $request) 15 { 16 $request->validate([ 17 'title' => 'required|string|max:255', 18 'category_name' => 'required|string|max:255', 19 'problem0' => 'required|string|max:255', 20 'problem1' => 'string|nullable|max:255', 21 'problem2' => 'string|nullable|max:255', 22 'problem3' => 'string|nullable|max:255', 23 'problem4' => 'string|nullable|max:255', 24 'problem5' => 'string|nullable|max:255', 25 'problem6' => 'string|nullable|max:255', 26 'problem7' => 'string|nullable|max:255', 27 'problem8' => 'string|nullable|max:255', 28 'problem9' => 'string|nullable|max:255', 29 ]); 30 31 $problem_desc = []; 32 $category_name = []; 33 foreach ($request->all() as $key=>$value) 34 { 35 if(preg_match('/problem/',$key)) 36 { 37 if($value !== null){ 38 39 $problem_desc[] = ['description' => $value]; 40 } 41 } 42 if(preg_match('/category_name/', $key) && $value !== null) 43 { 44 $category_name = [ 'name' => $value]; 45 } 46 } 47 48 $drill = new Drill; 49 50 Auth::user()->drills()->save($drill->fill($request->only(['title', 'user_id']))); 51 $drill->problems()->createMany($problem_desc); 52 $drill->category()->create($category_name); 53 54 return redirect('/drills/new')->with('flash_message', __('Registered.')); 55 } 56 57 public function update(Request $request, $id) 58 { 59 if(!ctype_digit($id)){ 60 return redirect('/drills/new')->with('flash_message', __('Invalid operation was performed.')); 61 } 62 63 $request->validate([ 64 'title' => 'required|string|max:255', 65 'category_name' => 'required|string|max:255', 66 'problem0' => 'required|string|max:255', 67 'problem1' => 'string|nullable|max:255', 68 'problem2' => 'string|nullable|max:255', 69 'problem3' => 'string|nullable|max:255', 70 'problem4' => 'string|nullable|max:255', 71 'problem5' => 'string|nullable|max:255', 72 'problem6' => 'string|nullable|max:255', 73 'problem7' => 'string|nullable|max:255', 74 'problem8' => 'string|nullable|max:255', 75 'problem9' => 'string|nullable|max:255', 76 ]); 77 78 $problem_desc = []; 79 $category_name = []; 80 foreach ($request->all() as $key=>$value) 81 { 82 if(preg_match('/problem/',$key)) 83 { 84 if($value !== null){ 85 86 $problem_desc[] = ['description' => $value]; 87 } 88 } 89 if(preg_match('/category_name/', $key) && $value !== null) 90 { 91 $category_name = [ 'name' => $value]; 92 } 93 } 94 95 $drill = new Drill; 96 97 $drill = Auth::user()->drills()->find($id); 98 Auth::user()->drills()->save($drill->fill($request->only(['title', 'user_id']))); 99 100 /* 101 フォームから入力した値をもとに、problemsテーブルとcategoriesテーブルを更新したい。 102 createメソッドと同じ処理にした場合、レコードが追加されてしまう。 103 */ 104 105 106 } 107
環境
PHP 7.2.5
Laravel 7.0
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。