きつね先生
わんぽち
きつね先生
CRUDとは「Create, Read, Update, Delete」の総称のことをいいます!
にゃんみ
きつね先生
にゃんみちゃん正解です!データベースにたいしてCRUD処理を実装できるようになると幅が広がりますのでぜひマスターしましょう!
こんにちは!あっきーです。
今回は Webアプリでおなじみの CRUD処理の実装をまとめてみました。
Web系のプログラミングをはじめたらまず最初にやるのではないかと思います。
前の記事でつくったWebアプリを元に機能追加していくのですが、すでに「Create, Read」の部分は記事にしていますので割愛させていただき、今回は「Update, Delete」の部分をやっていきます。
前の記事を見ていない方はまず以下を参考にベースを完成させてから読んでいただければと思います。
【Laravel】Web アプリをつくりながら Eloquent ORM モデルでのデータベース操作を学ぶ
きつね先生
今日はウェブアプリをつくりながらモデルのつかいかたを学んでいきましょう!
わんぽち
モデルをつかうとなにがいいんだわん?
きつね先生
...
【Laravel】ファイルアップロードの機能追加と一緒にマイグレーションで DB に変更をする方法
きつね先生
本日は既存のアプリへファイルアップロード機能の追加を行い、それに伴うデータベースの変更処理を勉強していきましょう!
わんぽち
むずかしそうだワン。。。...
それではまとめていきます。
完成イメージ
前回記事に以下画像のようなボタンやページを追加します。
・表示ページ
・編集ページ
・削除
ビューテンプレートの作成
以下の3つのファイルを作成します。
・編集ページ
resources/views/layouts/edit.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
@ extends ( 'layouts.testapp' )
@ section ( 'title' , 'comic.edit' )
@ section ( 'content' )
{ ! ! Form:: open ( [ 'url' = > '/comic/update' , 'method' = > 'post' , 'files' = > true ] ) ! ! }
< ! -- 更新カラムのid 送信 -- >
{ ! ! Form:: hidden ( 'id' , $comics -> id ) ! ! }
< ! -- 現在登録している画像データの表示 -- >
@ if ( $comics -> image )
< p > < img src = "/storage/images/{{$comics->image}}" alt = "images" width = "104" height = "150" > < / p >
@ else
< p > < img src = "/storage/images/Noimage_image.png" alt = "images" width = "104" height = "150" > < / p >
@ endif
< ! -- テキストボックス(コミック名)-- >
< div class = "form-group" >
{ { Form:: label ( 'comic' , 'コミック名' ) } }
{ { Form:: text ( 'comic_name' , $comics -> comic_name , [ 'class' = > 'form-control' , 'id' = > 'comic' ] ) } }
< / div >
< ! -- セレクトボックス(作者)-- >
< div class = "form-group" >
{ { Form:: label ( 'authors' , '作者' ) } }
< select name = "author_id" class = "form-control" id = "authors" >
@ foreach ( $authors as $author )
< option value = { { $author -> id } } @ if ( $author -> id == $comics -> author_id ) selected @ endif >
{ { $author -> author } }
< / option >
@ endforeach
< / select >
< / div >
< ! -- セレクトボックス(連載誌)-- >
< div class = "form-group" >
{ { Form:: label ( 'magazines' , '連載誌' ) } }
< select name = "magazine_id" class = "form-control" id = "magazines" >
@ foreach ( $magazines as $magazine )
< option value = { { $magazine -> id } } @ if ( $magazine -> id == $comics -> magazine_id ) selected @ endif >
{ { $magazine -> magazine } }
< / option >
@ endforeach
< / select >
< / div >
< ! -- テキストボックス(説明)-- >
< div class = "form-group" >
{ { Form:: label ( 'description' , '説明' ) } }
{ { Form:: text ( 'description' , $comics -> description , [ 'class' = > 'form-control' , 'id' = > 'description' ] ) } }
< / div >
< ! -- ファイル選択(画像)-- >
< div class = "form-group" >
< div class = "input-group" >
< label class = "input-group-btn" >
< span class = "btn btn-primary" >
画像選択< input type = "file" name = "image" style = "display:none;" id = "editFile" onchange = "getFileName('outFilename');" >
< input type = "hidden" name = "img" value = { { $comics -> image } } >
< / span >
< / label >
< input type = "text" class = "form-control" id = "outFilename" readonly >
< / div >
< / div >
< ! -- サブミット(編集)-- >
< div class = "form-group" >
{ ! ! Form:: submit ( '編集' , [ 'class' = > 'form-control' ] ) ! ! }
< / div >
{ ! ! Form:: close ( ) ! ! }
@ endsection
@ section ( 'footer' )
copyright 2019 ○○○.
@ endsection
・更新ページ
resources/views/layouts/update.blade.php
更新処理はコントローラで行い、完了したらインデックスページへリダイレクトしますのでこのファイルは編集データの Post 先として作成しただけですので今回は空で大丈夫です。
・削除ページ
resources/views/layouts/delete.blade.php
更新処理同様の理由でファイルは空で大丈夫です。
既存ファイルの編集
前回記事で作成した既存のファイルに以下の編集を加えてください。
・表示ページ
resources/views/comic/index.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
< table >
~省略~
@ if ( $item -> image )
< td >
< img src = "/storage/images/{{$item->image}}" alt = "images" width = "104" height = "150" >
< / td >
@ else
< td >
< img src = "/storage/images/Noimage_image.png" alt = "images" width = "104" height = "150" >
< / td >
@ endif
< ! -- ここから追加 -- >
< td >
< div class = "btn-toolbar" >
< div class = "btn-group" >
{ ! ! Form:: open ( [ 'url' = > '/comic/edit' , 'method' = > 'post' ] ) ! ! }
{ ! ! Form:: hidden ( 'id' , $item -> id ) ! ! }
< label class = "input-group-btn" >
< i class = "fas fa-edit" > < / i >
{ ! ! Form:: submit ( 'edit' , [ 'style' = > 'display:none' ] ) ! ! }
< / label >
{ ! ! Form:: close ( ) ! ! }
{ ! ! Form:: open ( [ 'url' = > '/comic/delete' , 'method' = > 'post' , 'onSubmit' = > 'return check()' ] ) ! ! }
{ ! ! Form:: hidden ( 'id' , $item -> id ) ! ! }
< label class = "input-group-btn" >
< i class = "fas fa-trash-alt" > < / i >
{ ! ! Form:: submit ( 'delete' , [ 'style' = > 'display:none' ] ) ! ! }
< / label >
{ ! ! Form:: close ( ) ! ! }
< / div >
< / div >
< / td >
< ! -- ここまで追加 -- >
< / tr >
@ endforeach
< / table >
<table></table> 内の画像表示の下辺りから上記ファイルを参考に追加してください。
・ベースレイアウト
resources/views/layouts/comicapp.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
< head >
< title > @ yield ( 'title' ) < / title >
< ! -- 追加:bootstrap の設定 -- >
< link rel = "stylesheet" href = "https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity = "sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin = "anonymous" >
< ! -- 追加:fontawesome の設定 -- >
< link rel = "stylesheet" href = "https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity = "sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin = "anonymous" >
<style>
~省略~
.form-group input {
width : 300px ;
}
.form-group select {
width : 300px ;
}
.form-group {
width : 300px ;
}
</style>
< / head >
< body >
~省略~
< ! -- 追加:アップロードファイル名を取得してinput タグに出力 -- >
<script>
function getFileName ( idname ) {
var outFrame = document . getElementById ( idname ) ;
var fileRef = document . getElementById ( 'editFile' ) ;
for ( i = 0 ; i < fileRef . files . length ; i ++ ) {
outFrame . value = fileRef . files [ i ] . name ;
}
}
</script>
< ! -- 追加:削除前にアラートを表示 -- >
<script type = "text/javascript" >
function check ( ) {
var del = confirm ( '削除しますか?' ) ;
if ( ! del == true ) {
return false ;
}
else {
return true ;
}
}
</script>
< ! -- 追加:bootstrap の設定 -- >
<script src = "https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity = "sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin = "anonymous" > </script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity = "sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin = "anonymous" > </script>
<script src = "https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity = "sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin = "anonymous" > </script>
< / body >
見た目に少し bootstrap と fontawesome を使用したので <head></head> 内に設定のリンクと CSS の微調整を追加してください。
あとは </body> の手前に追加、編集ページ共通のアップロードファイル名を表示するスクリプトと削除前のアラート表示のスクリプトと bootstrap の設定をはりつけます。
細かい説明は今回は割愛します。bootstrap や JS の記事も書いてますので参考にしてください。
そしてファイルかさばるの嫌でまとめていろいろ記述してごめんなさい(笑)
きちんとしたい方はファイルを分けて外部参照で CSS や JSを使用してください。
コントローラーの編集
前回記事で作成したコントローラの下に以下の修正を加えます。
app/HTTP/Controllers/ComicController.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/* 更新処理 */
public function edit ( Request $request ) {
$form = [
'comics' = > Comic:: find ( $request -> id ) ,
'magazines' = > Magazine:: all ( ) ,
'authors' = > Author:: all ( ) ,
] ;
return view ( 'comic.edit' , $form ) ;
}
public function update ( ComicRequest $request ) {
if ( isset ( $request -> image ) ) {
$path = $request -> file ( 'image' ) -> store ( 'images' , 'public' ) ;
$image = basename ( $path ) ;
} elseif ( isset ( $request -> img ) ) {
$image = $request -> img ;
} else {
$image = '' ;
}
$comic = Comic:: find ( $request -> id ) ;
$form = [
'comic_name' = > $request -> comic_name ,
'magazine_id' = > $request -> magazine_id ,
'author_id' = > $request -> author_id ,
'description' = > $request -> description ,
'image' = > $image ,
] ;
unset ( $form [ '_token' ] ) ;
$comic -> fill ( $form ) -> save ( ) ;
return redirect ( '/comic' ) ;
}
/* 削除処理*/
public function delete ( Request $request ) {
Comic:: find ( $request -> id ) -> delete ( ) ;
return redirect ( '/comic' ) ;
}
編集処理は追加処理とほとんど一緒です。
追加の時は「$comic = new Comic;」と新規インスタンスに対してリクエストから送信された値を「save();」でデータベースに追加してたのに対して、編集処理は「$comic = Comic::find($request->id);」とリクエストされた id を元に既存データベースのフィールドを探しそこに上書きするだけです。
削除に関してはリクエストされた id を元に対象のフィールドを「delete();」で削除するだけです。
ルーティング
最後にルーティングの設定です。以下のファイルを編集します
routes/web.php
/* 編集 */
Route:: post ( 'comic/edit' , 'ComicController@edit' ) ;
Route:: post ( 'comic/update' , 'ComicController@update' ) ;
/* 削除処理*/
Route:: post ( 'comic/delete' , 'ComicController@delete' ) ;
これで完成です。ブラウザにアクセスしたら完成イメージのようになっています。
さいごに
いかがでしたでしょうか。
データベースと CRUD 処理を覚えるとプログラミングの幅が広がりますよね。
次はセッションだったり API だったりそういうところも記事にしていけたらと思いますので引き続きよろしくおねがいします!
この記事を気に入っていただけましたらTwitter でもプログラミングのことについてツイートしていますので是非ご一緒にフォローの方もお願いします!
それでは次の記事でまたお会いしましょう!
・参考書籍