20
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Go】gorm のRecordNotFoundメソッドがsliceで結果を受け取ると必ずfalseになる

Last updated at Posted at 2017-12-10

gorm のRecordNotFoundがsliceで結果を受け取ると必ずfalseになる件

書いた経緯

GoのORMの一つであるgorm。
使っていて盛大にどハマりして、結局gormのソースを読むことになったのでその備忘

RecordNotFoundって何奴?

gormのリファレンスを見ると以下の感じです。

func (s *DB) RecordNotFound() bool
RecordNotFound check if returning ErrRecordNotFound error

ふむふむ。文面だけ読むとレコードがないエラーがあるかをチェックするらしい。

実際にソースにすると以下です。

main.go
type user struct {
	ID   int    `gorm:"column:id"`
	Name string `gorm:"column:name"`
}

func main(){

	db, _ := gorm.Open("mysql", "root@tcp(127.0.0.1:3306)/playground")
	result := user{}
	recordNotFound := db.Table("user").First(&result).RecordNotFound()
}

接続情報やらエラー処理やらを色々説明をすっ飛ばしますが、上記のように書けます
で、この場合は、レコードがないときはtrueを返してくれます

ちなみに,userテーブルの中身は空っぽでidとnameのカラムがあります。

さて、本題

以下の時の結果は果たしてどうなるでしょうか?

main.go
package main

import (
	"fmt"

	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

type user struct {
	ID   int    `gorm:"column:id"`
	Name string `gorm:"column:name"`
}

func main() {
	db, _ := gorm.Open("mysql", "root@tcp(127.0.0.1:3306)/playground")

	result := user{}
	recordNotFound := db.Table("user").First(&result).RecordNotFound()
	fmt.Print("structのとき=")
	fmt.Println(recordNotFound)

	resultSlice := []user{}
	recordNotFound = db.Table("user").First(&resultSlice).RecordNotFound()
	fmt.Print("sliceのとき=")
	fmt.Println(recordNotFound)

}

実行結果

$ go run main.go
recordNotFoundがstructのとき=true
recordNotFoundがsliceのとき=false

...実行結果が違う...だと。
そうです。slice型の時はRecordNotFoundエラーはなし。

gormのソースを見ると確かに,0件かつ、sliceでないときにエラーを格納しています。

callback_query.go
//~~省略~~
	if err := rows.Err(); err != nil {
		scope.Err(err)
	} else if scope.db.RowsAffected == 0 && !isSlice {
		scope.Err(ErrRecordNotFound)
	}
//~~省略~~

まとめ

結果があるかどうかを見たい時は

len(result) > 0

とする必要がある。

これに関する議論はissuesで語られており、
意識してこの形にしているみたいです。

20
5
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
20
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?