🚀

GORM?Omitって美味しいの?

に公開

Omitって何?

GORMでレコードを作成する時は下記のようにCreate()しますよね?

users := []*User{
    {Name: "Jinzhu", Age: 18, Birthday: time.Now()},
    {Name: "Jackson", Age: 19, Birthday: time.Now()},
}

result := db.Create(users) // pass a slice to insert multiple row

result.Error        // returns error
result.RowsAffected // returns inserted records count

はい。します。

そして、Omit!!!!!
そうすると、INSERT文からフィールド(Name,Age,CreatedAt)を省くことができます。

db.Omit("Name", "Age", "CreatedAt").Create(&user)
// INSERT INTO `users` (`birthday`,`updated_at`) VALUES ("2020-01-01 00:00:00.000", "2020-07-04 11:05:21.775")

何それ美味しいの?

  • DBでデフォルト値を設定している
  • DBでNullは許容されていない
  • メゾットからはDBへNullを投げようとしている

上記の際に、INSERTをそのままするとDBはNullを許容していないのでエラーが起きます。

しかし、DBのデフォルト値を使いたい!!メゾットにはデフォルト値を持たしたくない!!

そんな時はINSERTを投げる前に、Omitしてフィールドを省いてあげましょう!!
フィールドがないので、DBにはDBのデフォルト値が入ります👍

おまけ知識 with 公式ソースコード

// Omit specify fields that you want to ignore when creating, updating and querying
func (db *DB) Omit(columns ...string) (tx *DB) {
	tx = db.getInstance()

	if len(columns) == 1 && strings.ContainsRune(columns[0], ',') {
		tx.Statement.Omits = strings.FieldsFunc(columns[0], utils.IsValidDBNameChar)
	} else {
		tx.Statement.Omits = columns
	}
	return
}

こんなだから、

if name {
    db.Omit("Name").Create(&user)
}
if age {
    db.Omit("Age").Create(&user)
}
if createdAt {
    db.Omit("CreatedAt").Create(&user)
}

と書くと最後のCreatedAtしかOmitされません。
if文とかで、分岐している場合はスライスを作って、appendしていきましょう!

// 例:if分岐とOmitの組み合わせ
var omitFields []string
if name {
    omitFields = append(omitFields, "Name")
}
if age {
    omitFields = append(omitFields, "Age")
}
if createdAt {
    omitFields = append(omitFields, "CreatedAt")
}

result := db.Omit(omitFields...).Create(&user)

参考

https://gorm.io/ja_JP/docs/create.html
https://github.com/go-gorm/gorm/blob/master/chainable_api.go

Discussion