前提・実現したいこと
現在 Go(WAF: gin)およびgormをもちいて簡単なCRUD処理を行うAPIの構築を行っています。
その中で以下ように定義されるテーブルがあり、postリクエストでprogramおよびstudent_programsのデータを作成したいと考えています
go
1type Program struct { 2 gorm.Model 3 Title string `json:title` 4 Description string `json:description` 5 Link string `json:link` 6} 7type Student struct { 8 gorm.Model 9 Name string `json:name` 10 Nickname string `json:nickname` 11} 12type StudentProgram struct { 13 gorm.Model 14 StudentID uint `json:student_id` 15 ProgramID uint `json:program_id` 16}
ここで、以下のようなエンドポイントを作成しました。
go
1//controller structの定義部などは割愛 2func (pc ProgramController) Create (c *gin.Context){ 3 db := db.GetDB() //詳細は割愛(dbを*db.gorm型で取得) 4 program := entity.Program{} 5 now := time.Now() 6 7 err := c.BindJSON(&program) 8 if err != nil { 9 c.String(http.StatusBadRequest, "request is failed" + err.Error()) 10 } 11 12 program.CreatedAt = now 13 program.UpdatedAt = now 14 15 db.NewRecord(program) 16 res := db.Create(&program) 17 18 studentPrograms := []entity.StudentProgram{} 19 for studentId := range c.PostForm("students"){ 20 studentPrograms = append(studentProgram, entity.StudentProgram{StudentID: uint(studentId), ProgramID: program.ID}) 21 } 22 db.Create($studentPrograms) 23 24 if res.Error != nil { 25 c.JSON(http.StatusOK, program) 26 } 27}
このエンドポイントに対して、以下のようなbodyを持つpost requestを送信しました
json
1{ 2 "title": "title1", 3 "description": "description1", 4 "link": "https://www.example1.com", 5 "students": [1, 2, 3] 6}
上記リクエストにより、programsにデータが1行insertされ、student_programsにデータが3行insertされている状況が理想です。
実行結果, 試したこと
実行結果
上記リクエストの結果、以下のようなエラーがおこり、student_programsにデータがinsertされませんでした(programsにはデータがinsertされていました)
reflect: call of reflect.Value.Interface on zero Value
試したこと
fmt.Println(studentPrograms)
で、for文の結果studentProgramsが正しく構成されているかをチェックした => studentProgramsは空のlistになっていたfmt,Println(c.PostForm("students"))
でstudentsパラメータが取得できるかをチェックした => 標準出力には何も表示されなかった
お聞きしたいこと
- ginをつかったpost requestでrequest bodyを受け取る方法はc.PostFormでただしいか
- 上記の方法でデータinsertがうまくいかないのはなぜか
- 親子のデータの同時作成において上機能方法は効率的といえるか(もっとよい書き方があるか)
以上、素人質問で恐縮ですがよろしくお願いいたします。
エラー表示のソース行は問題を読み解く重要な情報で、
「reflect: call of reflect.Value.Interface on zero Value」だけを示されても
何が起こっているのかを言い当てられる人はいないと思います。
可能であればミニマムに実行可能なコードに切り出してみてください。
またはエラー該当行の切り出しを示すなどしてもらえると回答がつきやすくなると思います。
あと、以下のようにgormのエラーハンドリングをもれなくやりましょう。
if db.Create($studentPrograms).Error != nil {
...
}
あなたの回答
tips
プレビュー