はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。
GoのフレームワークであるGinを中心に、
webアプリ開発学習をしていきます。
バックエンドエンジニアになるまでの学習内容は以前投稿した以下の記事を基にしています。
本日の学習内容
GinのTutorialで作成したAPIを改造して、簡素なWebアプリを作成しようと思います
- GinとGORMを使用したAPIにキーワード検索機能追加 ←Topics!!
GinとGORMを使用したAPIにキーワード検索機能追加
先日投稿したコチラの記事
で作成した簡素なアプリにキーワード検索機能を追加しました。
前回から変更点したファイルのみ記述します。
追加した検索機能でできるようになったことは、以下になります。
- indexページの検索フォームでArtistに関するワードを入力
- 検索ワードをもとに
GetAlbumsByKeyword
メソッドで部分一致するalbumsデータを取得 - keyalbumlistページで検索結果の一覧を表示
- 一覧からUpdate,Deleteの実行 or indexページに戻る
app/controllers
webserver.go
package controllers
import (
"ginapp-albums/app/models"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
)
type AlbumHandler struct {
Db *gorm.DB
}
func (h *AlbumHandler) GetAlbums() []models.Album {
var albums []models.Album
h.Db.Find(&albums)
return albums
}
func (h *AlbumHandler) InsertAlbums(c *gin.Context) {
var albumRequest models.Album
if err := c.Bind(&albumRequest); err != nil {
albums := h.GetAlbums()
c.HTML(http.StatusBadRequest, "index.html", gin.H{"albums": albums, "err": err})
c.Abort()
} else {
title, _ := c.GetPostForm("title")
artist, _ := c.GetPostForm("artist")
price, _ := c.GetPostForm("price")
floatprice, _ := strconv.ParseFloat(price, 64)
h.Db.Create(&models.Album{Title: title, Artist: artist, Price: floatprice})
c.Redirect(http.StatusMovedPermanently, "/albums")
}
}
func (h *AlbumHandler) GetAlbumByID(c *gin.Context) {
id := c.Param("id")
checkId, err := strconv.Atoi(id)
if err != nil {
panic(err)
}
album := models.Album{}
h.Db.First(&album, checkId)
c.HTML(http.StatusOK, "update.html", gin.H{"album": album})
}
func (h *AlbumHandler) UpdateAlbumByID(c *gin.Context) {
id := c.Param("id")
checkId, err := strconv.Atoi(id)
if err != nil {
panic(err)
}
var album models.Album
var albumRequest models.Album
if err := c.Bind(&albumRequest); err != nil {
albums := h.GetAlbums()
c.HTML(http.StatusBadRequest, "index.html", gin.H{"albums": albums, "err": err})
c.Abort()
} else {
title, _ := c.GetPostForm("title")
artist, _ := c.GetPostForm("aritst")
price, _ := c.GetPostForm("price")
floatprice, _ := strconv.ParseFloat(price, 64)
h.Db.First(&album, checkId)
album.Title = title
album.Artist = artist
album.Price = floatprice
h.Db.Save(&album)
c.Redirect(http.StatusMovedPermanently, "/albums")
}
}
func (h *AlbumHandler) DeleteAlbumByID(c *gin.Context) {
id := c.Param("id")
checkId, err := strconv.Atoi(id)
if err != nil {
panic(err)
}
var album models.Album
h.Db.First(&album, checkId)
h.Db.Delete(&album)
c.Redirect(http.StatusMovedPermanently, "/albums")
}
func (h *AlbumHandler) GetAlbumsByKeyword(c *gin.Context) {
keyword, _ := c.GetPostForm("keyword")
var albums []models.Album
h.Db.Where("artist Like ?", "%"+keyword+"%").Find(&albums)
c.HTML(http.StatusOK, "keyalbumlist.html", gin.H{"albums": albums})
}
route.go
package controllers
import (
"net/http"
"time"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
)
func NewRoutes(dbConn *gorm.DB) {
albumHandler := AlbumHandler{
Db: dbConn,
}
router := gin.Default()
router.Use(cors.New(cors.Config{
AllowOrigins: []string{"*"},
AllowMethods: []string{"PUT", "PATCH", "DELETE", "POST", "GET"},
AllowHeaders: []string{"Origin"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
AllowOriginFunc: func(origin string) bool {
return origin == "*"
},
MaxAge: 12 * time.Hour,
}))
router.LoadHTMLGlob("app/views/*.html")
router.GET("/albums", func(c *gin.Context) {
albums := albumHandler.GetAlbums()
c.HTML(http.StatusOK, "index.html", gin.H{"albums": albums})
})
router.GET("/albums/:id", albumHandler.GetAlbumByID)
router.POST("/albums/new", albumHandler.InsertAlbums)
router.POST("/albums/update/:id", albumHandler.UpdateAlbumByID)
router.POST("/albums/delete/:id", albumHandler.DeleteAlbumByID)
router.POST("/albums/search", albumHandler.GetAlbumsByKeyword)
router.Run("localhost:8080")
}
app/views
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>AlbumsList</title>
</head>
<body>
<h1><a href="/albums">AlbumListApp</a></h1>
<h2>Add Album</h2>
<form method="POST" action="/albums/new">
<p>Title <input type="text" name="title" value="{{.album.Title}}" size="30" placeholder="Input Title"></p>
<p>Artist <input type="text" name="artist" value="{{.album.Artist}}" size="30" placeholder="Input Artist"></p>
<p>Price <input type="text" name="price" value="{{.album.Price}}" size="30" placeholder="Input Price"></p>
<p><input type="submit" value="Send"></p>
</form>
<h2>ArtistName Search</h2>
<form action="/albums/search" method="POST">
<p>ArtistName <input type="text" name="keyword" size="30" placeholder="Input ArtistName"></p>
<p><input type="submit" value="Search"></p>
</form>
<ul>
{{ range .albums }}
<li>ID:{{ .ID }} Title:{{ .Title }} Artist:{{ .Artist }} Price:{{ .Price }}
<label><a href="/albums/{{.ID}}">UPDATE</a></label>
<label><form action="/albums/delete/{{.ID}}" method="POST"><input type="submit" value="DELETE"></form></label>
</li>
{{end}}
</ul>
</body>
</html>
keyalbumlist.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>AlbumsList</title>
</head>
<body>
<h1><a href="/albums">AlbumListApp</a></h1>
<ul>
{{ range .albums }}
<li>ID:{{ .ID }} Title:{{ .Title }} Artist:{{ .Artist }} Price:{{ .Price }}
<label><a href="/albums/{{.ID}}">UPDATE</a></label>
<label><form action="/albums/delete/{{.ID}}" method="POST"><input type="submit" value="DELETE"></form></label>
</li>
{{end}}
</ul>
<a href="/albums">Return</a>
</body>
</html>
使用している教材はこちら↓
おわりに
最後までお読みいただきありがとうございました。
アドバイス・応援コメント等いただけますと幸いです。