前提・実現したいこと
golang(フレームワークはginです)で、
DBへinsertする際のstructやfunctionについて、より簡潔に、わかりやすく、疎結合に書きたいです。
しかし知見がなく、お詳しい方、良い方法をご教示願えませんでしょうか。
前提としては、下記のようなstructがあります。ORMはgormです。
go
1package entity 2 3import "github.com/jinzhu/gorm" 4 5// マイグレーション用 6type Post struct { 7 UserId uint64 `gorm:"type:int; "` //型は変更不可 8 PostImageId int `gorm:"type:int; "`//型は変更不可 9 DogName string `gorm:"type:varchar(30); "`//型は変更不可 10 OtherMessage string `gorm:"type:varchar(4000);"`//型は変更不可 11}
go
1package main 2router.POST("/addRecord", controller.Create)// レコードをDBへ登録する
発生している問題・エラーメッセージ
controllerでは、クライアントから受けたパラメタを
上記に示したstructentity.Post
(マイグレーション用の構造体)型の変数record
に入れ、
下記の通りDBへInsertしています。
ここで面倒なこととして、受けたパラメタはstring型
、
entity.Post
の各フィールドはuint型
やint型
があるため、全て各フィールドに沿った変換をする必要があります。
go
1package controller 2 3func Create(c *gin.Context) { 4 userId, _ := strconv.ParseUint(c.PostForm("user_id"), 10, 64) //stringからUintに変換する 5 postImageId, _ := strconv.ParseInt(c.PostForm("post_image_id")) //stringからintに変換する 6 7 // テーブルに登録するためのレコード情報 8 var record = entity.Post{ 9 UserId: userId, //変換したUintを格納する 10 PostImageId: postImageId,//変換したintを格納する 11 DogName: c.PostForm("dog_name"), 12 OtherMessage: c.PostForm("other_message"), 13 } 14 db.InsertRecord(&record) // -> 下記コードブロックへ 15 c.JSON(http.StatusCreated, "*****created") 16}
go
1package db 2 3func InsertRecord(registerRecord *entity.Post) { //entity.Post型の引数で受ける 4 db := open() 5 db.Create(®isterRecord) // insert 6 defer db.Close() 7}
controllerで行っているこの型変換作業の羅列は美しくなく(実際は膨大な量のフィールドを変換しています)、
またマイグレーション用のstructをCRUDにも使っていることは、あまりよくないと感じています。
試したこと
以下、テーブル設計のためのstructと、insertのためのstructを切り分けるために、私が考えた案です。
お詳しいかた、どのような方法が賢いか、ご教示願えませんでしょうか。
案A:INSERT用のstructを使用する。
今使用しているstructentity.Post
(マイグレーション用struct)を使用せず、
entity.DTOPost
というstructを用意します。
全てstring
なので、Create()
では、受けたパラメタを変換せずそのまま格納できます。
go
1package entity 2 3// CRUD用(編集中) 4type DTOPost struct { 5 UserId string 6 PostImageId string 7 DogName string 8 OtherMessage string 9}
しかし、gorm(ORM)の機能上、struct名がそのままinsert先のテーブル名指定になります。
つまり、ここでは本当はPost
テーブルにinsertしたいが、DTOPost
テーブルにinsertしてしまうことになります。
公式をみたところ、insert先のテーブル名を指定できる機能はなさそうでした。
https://gorm.io/ja_JP/docs/create.html
案B:パッケージを分ける
同じパッケージに同名structを持つことはできないので、
ディレクトリ(パッケージ)を分けて、structPost
を作成する。
go
1package other 2 3// CRUD用(編集中) 4type Post struct { 5 UserId string 6 PostImageId string 7 DogName string 8 OtherMessage string 9}
go
1package db 2 3func InsertRecord(registerRecord *other.Post) { //other.Post型の引数で受ける 4 db := open() 5 db.Create(®isterRecord) // insert 6 defer db.Close() 7}
(B案は試していませんが、洗練された方法ではないかな、と感じています。)
案C:その他
今はinsertのためにマイグレーション用structをそのまま使っており、
そもそもマイグレーション用の構造体をinsertでも使用することに違和感もあります。
長々とすみません、
お詳しいかた、どのような方法が賢いか、ご教示願えませんでしょうか。
あなたの回答
tips
プレビュー