LoginSignup
0
0

More than 1 year has passed since last update.

【#47 エンジニア転職学習】GinTutorialのWebApp改造 キーワード検索機能追加

Last updated at Posted at 2022-08-07

はじめに

富山県に住んでいる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>
使用している教材はこちら↓

おわりに

最後までお読みいただきありがとうございました。
アドバイス・応援コメント等いただけますと幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0