如何仅更新在我的结构中填充的字段在BD中?

huangapple go评论76阅读模式
英文:

How to update in BD only the fields filled in my struct?

问题

我有一个结构体用于从用户那里获取数据并更新数据库中的信息。然而,如果用户将某个字段留空,对应的数据库字段也将留空。我不希望这样,我只想编辑用户提供的字段。

我的模型:

type Business struct {
    Id           uint64 `json:"id,omitempty"`
    Company_name string `json:"company_name,omitempty"`
    Trading_name string `json:"trading_name,omitempty"`
    Facebook     string `json:"facebook,omitempty"`
    Instagram    string `json:"instagram,omitempty"`
    Tel          string `json:"tel,omitempty"`
    User_id      uint64 `json:"user_id,omitempty"`
}

我的控制器:

func EditBusinessInfo(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    businessIDParams, err := strconv.ParseUint(params["businessID"], 10, 64)
    if err != nil {
        returns.ERROR(w, http.StatusBadRequest, err)
        return
    }

    userIDInToken, err := auth.ExtractUserID(r)
    if err != nil {
        returns.ERROR(w, http.StatusInternalServerError, err)
        return
    }

    db, err := db.ConnectToDB()
    if err != nil {
        returns.ERROR(w, http.StatusInternalServerError, err)
        return
    }
    defer db.Close()

    repository := repositories.NewUsersRepository(db)
    businessInBD, err := repository.GetBusiness(businessIDParams)
    if err != nil {
        returns.ERROR(w, http.StatusInternalServerError, err)
        return
    }

    if userIDInToken != businessInBD.User_id {
        returns.ERROR(w, http.StatusUnauthorized, errors.New("你不能编辑其他人的公司"))
        return
    }

    if businessIDParams != businessInBD.Id {
        returns.ERROR(w, http.StatusForbidden, errors.New("这个公司不属于你"))
        return
    }

    bodyRequest, err := ioutil.ReadAll(r.Body)
    if err != nil {
        returns.ERROR(w, http.StatusBadRequest, err)
        return
    }

    var business models.Business

    if err := json.Unmarshal(bodyRequest, &business); err != nil {
        returns.ERROR(w, http.StatusUnprocessableEntity, err)
        return
    }

    if err := repository.EditBusinessInfo(userIDInToken, business); err != nil {
        returns.ERROR(w, http.StatusInternalServerError, err)
        return
    }

    returns.JSON_RESPONSE(w, http.StatusOK, nil)
}

以上是您提供的代码的翻译。

英文:

I have a struct to get the data from the user and update the info in the database. However, if the user lets a field in a blank, the correspondent field into DB will be blank. I don't want that, I would like to edit only the fields that the user informed.

My model:

type Business struct {
Id           uint64 `json:"id,omitempty"`
Company_name string `json:"company_name,omitempty"`
Trading_name string `json:"trading_name,omitempty"`
Facebook     string `json:"facebook,omitempty"`
Instagram    string `json:"instagram,omitempty"`
Tel          string `json:"tel,omitempty"`
User_id      uint64 `json:"user_id,omitempty"`
}

My controller:

func EditBusinessInfo(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
businessIDParams, err := strconv.ParseUint(params["businessID"], 10, 64)
if err != nil {
returns.ERROR(w, http.StatusBadRequest, err)
return
}
userIDInToken, err := auth.ExtractUserID(r)
if err != nil {
returns.ERROR(w, http.StatusInternalServerError, err)
return
}
db, err := db.ConnectToDB()
if err != nil {
returns.ERROR(w, http.StatusInternalServerError, err)
return
}
defer db.Close()
repository := repositories.NewUsersRepository(db)
businessInBD, err := repository.GetBusiness(businessIDParams)
if err != nil {
returns.ERROR(w, http.StatusInternalServerError, err)
return
}
if userIDInToken != businessInBD.User_id {
returns.ERROR(w, http.StatusUnauthorized, errors.New("você não pode editar a empresa de outra pessoa"))
return
}
if businessIDParams != businessInBD.Id {
returns.ERROR(w, http.StatusForbidden, errors.New("essa empresa não peertence a você"))
return
}
bodyRequest, err := ioutil.ReadAll(r.Body)
if err != nil {
returns.ERROR(w, http.StatusBadRequest, err)
return
}
var business models.Business
if err := json.Unmarshal(bodyRequest, &business); err != nil {
returns.ERROR(w, http.StatusUnprocessableEntity, err)
return
}
if err := repository.EditBusinessInfo(userIDInToken, business); err != nil {
returns.ERROR(w, http.StatusInternalServerError, err)
return
}
returns.JSON_RESPONSE(w, http.StatusOK, nil)
}

答案1

得分: 1

一个 int 和 string 都有默认值,所以如果你不给它们赋值,它们将被填充为它们的默认值(0 或 "")。由于它们总是被赋予一个值,omitempty 标签将永远不会起作用。

解决这个问题的常见方法是将结构体字段设置为指针,如果指针没有设置,则为 nil。nil 值将触发 json marshaler 识别 omitempty 标签。当你将这些值插入到数据库时,它们也将为 null/nil。

你应该评估哪些字段需要一个值,哪些字段可以允许为空,以防你的数据库有完整性约束。在处理数据时,你还需要在代码中添加 nil 检查。

英文:

An int and string both have default values, so if you don't assign a value to them they will be populated with their default value (0 or ""). Since they will always have a value assigned, the omitempty tag will never come into play.

A common solution to this issue is to make your struct fields be pointers, if a pointer isn't set then it is nil. the nil value will then trigger the json marshaler to recognize the omitempty tag. And when you insert to you DB those values will be null/nil as well.

You should evaluate which fields need a value and which can be allowed to be empty in case your DB has integrity constraints. You will also have to add nil checks in your code when working with data.

huangapple
  • 本文由 发表于 2021年6月7日 19:52:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/67871155.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定