Describe the feature

Currently if you call AddCars([]Cars{}) it will throw an error on DB layer, instead of success message, as this is command that resulted object might be empty, checking for len(cars) feels very redundant for each call

func AddCars(cars []Car) error {
    return DB.Clauses(clause.OnConflict{
        Columns:   []clause.Column{{Name: "id"}},
        DoUpdates: clause.AssignmentColumns([]string{"updated_at"}),
    }).Create(&cars).Error
}
/cars.go:1 empty slice found
[0.027ms] [rows:0] INSERT INTO "cars" ("updated_at","id") VALUES  ON CONFLICT ("id") DO UPDATE SET "updated_at"="excluded"."updated_at"

Motivation

Current workaround

func AddCars(cars []Car) error {
    if len(cars) == 0 {
        return nil
    }
    return DB.Clauses(clause.OnConflict{
        Columns:   []clause.Column{{Name: "id"}},
        DoUpdates: clause.AssignmentColumns([]string{"updated_at"}),
    }).Create(&cars).Error
}

Any chance to improve this?

Related Issues

Comment From: jinzhu

I would like to keep current behaviour, to make sure this is the expected situation.

Comment From: vikmeup

I would like to keep current behaviour, to make sure this is the expected situation.

Is it worth adding as customizable parameter into gorm config?

Comment From: wchargin

I would like to keep current behaviour, to make sure this is the expected situation.

In the last 24 hours, I have run into two bugs in two entirely separate production systems that were due to this design choice. In each case, the fix was to add an if len(xs) > 0 guard around the db.Save; in each case, the original author of the code was surprised that that was necessary.

Go proverbs say, "make the zero value useful". slices.Sort([]int{}) doesn't panic. buffer.Write([]byte{}) doesn't return an error. This choice just forces callers to make an extra check and breaks long-standing API design principles by introducing a removable discontinuity. Please reconsider.