Как правильно обрабатывать отправку формы в beego?

Я пытаюсь отправить данные формы в beego и сохранить их в базе данных. И есть несколько вопросов:

  • как правильно обработать запрос и преобразовать его в объект?
  • Должен ли я проверять запрос или преобразованный объект?

Мое действие контроллера:

func (c *ServicesController) Edit() {
    var err error
    var id, _ = c.GetUint64(":id")
    var serviceModel = models.Service{}
    var service models.Service

    service, err = serviceModel.FindById(id)

    c.Data["Service"] = service

    if err == orm.ErrNoRows || err == orm.ErrMissPK  {
        c.Abort("404")
    }

    if c.Ctx.Input.IsPost() {
        err = nil
        if err := c.ParseForm(&service); err != nil {
            c.Abort("500")
        }

        serviceModel.CreateOrUpdate(service)
    }

    c.TplName = "services/edit.html"
}

Модель:

type Service struct {
    Id       uint64 `form:"-"`
    Name     string `orm:"size(100)" valid:"Required; MaxSize(100)" form:"name"`
}

func init() {
    orm.RegisterModel(new(Service))
}

func (s *Service) FindById(id uint64) (Service, error) {
    o := orm.NewOrm()
    service := Service{Id: id}
    err := o.Read(&service)

    return service, err
}

func (s *Service) CreateOrUpdate(service Service)  {
    o := orm.NewOrm()
    o.InsertOrUpdate(&service)
}

Но когда я пытаюсь отправить форму (с InsertOrUpdate), он все равно создает новый объект, потому что у меня нет поля id в форме (потому что я извлекаю объект из параметра id из маршрута). Должен ли я в любом случае передавать id для формы или как его взломать?


person Oleksandr Savchenko    schedule 19.04.2017    source источник


Ответы (1)


Просто добавьте идентификатор после разбора формы:

if err := c.ParseForm(&service); err != nil {
    c.Abort("500")
}
service.Id = id

Просматривая исходный код beego, я думаю, что вы могли бы сделать:

if c.Ctx.Input.IsPost() {
    c.Input().Add("id", id)
    err = nil
    if err := c.ParseForm(&service); err != nil {
        c.Abort("500")
    }

    serviceModel.CreateOrUpdate(service)
}

Но если нет, я бы просто немного изменил структуру вашего кода:

func (c *ServicesController) Edit() {
    var id, _ = c.GetUint64(":id")
    var service models.Service{}
    var serviceModel = models.Service{}
    var err error

    if c.Ctx.Input.IsPost() {
        if err = c.ParseForm(&service); err != nil {
            c.Abort("500")
        }
        service.Id = id
        serviceModel.CreateOrUpdate(service)
    } else {
        service, err = serviceModel.FindById(id)
        if err == orm.ErrNoRows || err == orm.ErrMissPK  {
        c.Abort("404")
    }

    c.Data["Service"] = service
    c.TplName = "services/edit.html"
}
person dave    schedule 19.04.2017
comment
Я тоже об этом думаю, а разве это не некрасиво? Я получаю объект из базы данных и применяю к нему данные формы. Почему он переопределяет идентификатор, которого нет в форме? - person Oleksandr Savchenko; 20.04.2017
comment
Вы должны показать нам свой метод ParseForm, я понятия не имею, почему он перезаписывает его. - person dave; 20.04.2017
comment
Это не мое, это от beego - person Oleksandr Savchenko; 20.04.2017