Gorm возвращает пустой объект вместо объекта по умолчанию, когда значение не найдено - PullRequest
0 голосов
/ 07 декабря 2018

Я сделал MySQL-запрос, используя GORM, внутри небольшого приложения go.

Я объявил свою domain struct

type Domain struct {
    gorm.Model
    Name string
    ...
}

Затем, когда я отправляю запрос в MySQL с помощью GORM сэтот метод.

func DomainInfos(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    w.WriteHeader(http.StatusOK)

    var d Domain

    config.DbConnection.Where("name = ?", vars["domain"]).Find(&d)

    json.NewEncoder(w).Encode(d)
}

Когда домен не найден, он возвращает объект по умолчанию из моего определения структуры

{
    {0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} 
    0
    0
    0
}

Поэтому я написал небольшое условие, чтобы вручную вернуть пустой объект

if d.ID == 0 {
    json.NewEncoder(w).Encode(make(map[string]string))
    return
}

Возможно ли, чтобы GORM возвращал пустой объект напрямую, когда запрос ничего не возвращает, чтобы избежать этой ручной проверки?

1 Ответ

0 голосов
/ 07 декабря 2018

GORM - это , возвращающий пустой объект;когда дело доходит до значений Go, «пусто» и «по умолчанию» совпадают и фактически называются нулевым значением .В вашей ситуации вам нужно контролировать вывод JSON, а не возвращаемое значение GORM.

Вы можете добавить тег omitempty к своим полям, чтобы исключить их из вывода JSON, если они содержат нулевое значениедля их типа:

type Domain struct {
    gorm.Model
    Name string `json:",omitempty"`
    ...
}

Для каждого поля с этим тегом, когда вы вызываете Encode или Marshal, если поле содержит нулевое значение (например, для Name, то есть string, если оно равно ""), поле не будет включено в вывод.Если вы пометите все экспортированные поля таким образом, и все они будут содержать свои нулевые значения, на выходе будет пустой объект JSON {}.

Также обратите внимание, что это:

json.NewEncoder(w).Encode(make(map[string]string))

Эквивалентно, но значительно менее эффективно, чем:

w.Write([]byte("{}"))

Другим вариантом будет пользовательский маршал, примерно такой:

func (d Domain) MarshalJSON() ([]byte, error) {
    if t.ID == 0 {
        return []byte("{}"), nil
    }

    // Wrap the type to avoid infinite recursion on MarshalJSON
    type dd Domain
    return json.Marshal(dd(d))
}

Рабочий пример можно посмотреть здесь:https://play.golang.org/p/mIRfRKXeyyW

...