質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

2073閲覧

Laravelでリレーションのあるテーブルが更新できない

yoshiba718

総合スコア5

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

1クリップ

投稿2020/04/29 11:58

編集2020/04/29 11:59

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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決しました。
今回のテーブル設計では、対象のレコードをピンポイントで更新するのは難しいと判断し、対象レコードを一度削除した後に改めて値を挿入する形にしました。

以下、updateメソッドのみを抜粋したものです。

php

1 public function update(InputDrillRequest $request, $id) 2 { 3 // GETパラメータが数字かどうかをチェックする 4 if(!ctype_digit($id)){ 5 return redirect('/drills/new')->with('flash_message', __('Invalid operation was performed.')); 6 } 7 8 $problem_desc = []; 9 $category_name = []; 10 foreach ($request->all() as $key=>$value) 11 { 12 if(preg_match('/problem/',$key) && $value !== null) 13 { 14 $problem_desc[] = [ 15 'description' => $value, 16 'form_num' => mb_substr($key,-1) 17 ]; 18 19 } 20 if(preg_match('/category_name/', $key) && $value !== null) 21 { 22 $category_name = [ 'name' => $value]; 23 } 24 } 25 26 $drill = Auth::user()->drills()->find($id); 27 Auth::user()->drills()->save($drill->fill($request->only(['title', 'user_id']))); 28 29 $drill = Drill::find($id); 30 $drill->problems()->delete(); 31 $drill->problems()->createMany($problem_desc); 32 33 $drill->category()->delete(); 34 $drill->category()->create($category_name); 35 36 37 return redirect('/drills')->with('flash_message', __('Registered.')); 38 }

投稿2020/05/01 10:22

yoshiba718

総合スコア5

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問