func (tr *TodoResource) UpdateTodo(c *gin.Context) {
	id, err := tr.getId(c)
	if err != nil {
		c.JSON(400, api.NewError("problem decoding id sent"))
		return
	}

	var todo api.Todo

	if !c.Bind(&todo) {
		c.JSON(400, api.NewError("problem decoding body"))
		return
	}
	todo.Id = int32(id)

	var existing api.Todo

	if tr.db.First(&existing, id).RecordNotFound() {
		c.JSON(404, api.NewError("not found"))
	} else {
		tr.db.Save(&todo)
		c.JSON(200, todo)
	}

}
func (tr *TodoResource) PatchTodo(c *gin.Context) {
	id, err := tr.getId(c)
	if err != nil {
		c.JSON(400, api.NewError("problem decoding id sent"))
		return
	}

	// this is a hack because Gin falsely claims my unmarshalled obj is invalid.
	// recovering from the panic and using my object that already has the json body bound to it.
	var json []api.Patch
	defer func() {
		if r := recover(); r != nil {
			if json[0].Op != "replace" && json[0].Path != "/status" {
				c.JSON(400, api.NewError("PATCH support is limited and can only replace the /status path"))
				return
			}

			var todo api.Todo

			if tr.db.First(&todo, id).RecordNotFound() {
				c.JSON(404, api.NewError("not found"))
			} else {
				todo.Status = json[0].Value

				tr.db.Save(&todo)
				c.JSON(200, todo)
			}
		}
	}()
	c.Bind(&json)
}
func (tr *TodoResource) CreateTodo(c *gin.Context) {
	var todo api.Todo

	if !c.Bind(&todo) {
		c.JSON(400, api.NewError("problem decoding body"))
		return
	}
	todo.Status = api.TodoStatus
	todo.Created = int32(time.Now().Unix())

	tr.db.Save(&todo)

	c.JSON(201, todo)
}