// CreateChild runs the create-child action. func (c *AreaController) CreateChild(ctx *app.CreateChildAreaContext) error { _, err := login.ContextIdentity(ctx) if err != nil { return jsonapi.JSONErrorResponse(ctx, goa.ErrUnauthorized(err.Error())) } parentID, err := uuid.FromString(ctx.ID) if err != nil { return jsonapi.JSONErrorResponse(ctx, goa.ErrNotFound(err.Error())) } return application.Transactional(c.db, func(appl application.Application) error { parent, err := appl.Areas().Load(ctx, parentID) if err != nil { return jsonapi.JSONErrorResponse(ctx, goa.ErrNotFound(err.Error())) } reqArea := ctx.Payload.Data if reqArea.Attributes.Name == nil { return jsonapi.JSONErrorResponse(ctx, errors.NewBadParameterError("data.attributes.name", nil).Expected("not nil")) } childPath := area.ConvertToLtreeFormat(parentID.String()) if parent.Path != "" { childPath = parent.Path + pathSepInDatabase + childPath } newArea := area.Area{ SpaceID: parent.SpaceID, Path: childPath, Name: *reqArea.Attributes.Name, } err = appl.Areas().Create(ctx, &newArea) if err != nil { return jsonapi.JSONErrorResponse(ctx, err) } res := &app.AreaSingle{ Data: ConvertArea(appl, ctx.RequestData, &newArea, addResolvedPath), } ctx.ResponseData.Header().Set("Location", rest.AbsoluteURL(ctx.RequestData, app.AreaHref(res.Data.ID))) return ctx.Created(res) }) }
// Create runs the create action. func (c *SpaceAreasController) Create(ctx *app.CreateSpaceAreasContext) error { _, err := login.ContextIdentity(ctx) if err != nil { return jsonapi.JSONErrorResponse(ctx, goa.ErrUnauthorized(err.Error())) } spaceID, err := uuid.FromString(ctx.ID) if err != nil { return jsonapi.JSONErrorResponse(ctx, goa.ErrNotFound(err.Error())) } // Validate Request if ctx.Payload.Data == nil { return jsonapi.JSONErrorResponse(ctx, errors.NewBadParameterError("data", nil).Expected("not nil")) } reqIter := ctx.Payload.Data if reqIter.Attributes.Name == nil { return jsonapi.JSONErrorResponse(ctx, errors.NewBadParameterError("data.attributes.name", nil).Expected("not nil")) } return application.Transactional(c.db, func(appl application.Application) error { _, err = appl.Spaces().Load(ctx, spaceID) if err != nil { return jsonapi.JSONErrorResponse(ctx, goa.ErrNotFound(err.Error())) } newArea := area.Area{ SpaceID: spaceID, Name: *reqIter.Attributes.Name, } err = appl.Areas().Create(ctx, &newArea) if err != nil { return jsonapi.JSONErrorResponse(ctx, err) } res := &app.AreaSingle{ Data: ConvertArea(appl, ctx.RequestData, &newArea, addResolvedPath), } ctx.ResponseData.Header().Set("Location", rest.AbsoluteURL(ctx.RequestData, app.AreaHref(res.Data.ID))) return ctx.Created(res) }) }
func createAreaLinks(request *goa.RequestData, id interface{}) *app.GenericLinks { selfURL := rest.AbsoluteURL(request, app.AreaHref(id)) return &app.GenericLinks{ Self: &selfURL, } }
// ConvertArea converts between internal and external REST representation func ConvertArea(appl application.Application, request *goa.RequestData, ar *area.Area, additional ...AreaConvertFunc) *app.Area { areaType := area.APIStringTypeAreas spaceType := "spaces" spaceID := ar.SpaceID.String() selfURL := rest.AbsoluteURL(request, app.AreaHref(ar.ID)) childURL := rest.AbsoluteURL(request, app.AreaHref(ar.ID)+"/children") spaceSelfURL := rest.AbsoluteURL(request, app.SpaceHref(spaceID)) pathToTopMostParent := pathSepInService + area.ConvertFromLtreeFormat(ar.Path) // /uuid1/uuid2/uuid3s i := &app.Area{ Type: areaType, ID: &ar.ID, Attributes: &app.AreaAttributes{ Name: &ar.Name, CreatedAt: &ar.CreatedAt, Version: &ar.Version, ParentPath: &pathToTopMostParent, }, Relationships: &app.AreaRelations{ Space: &app.RelationGeneric{ Data: &app.GenericData{ Type: &spaceType, ID: &spaceID, }, Links: &app.GenericLinks{ Self: &spaceSelfURL, }, }, Children: &app.RelationGeneric{ Links: &app.GenericLinks{ Self: &childURL, }, }, }, Links: &app.GenericLinks{ Self: &selfURL, }, } // Now check the path, if the path is empty, then this is the topmost area // in a specific space. if ar.Path != "" { allParents := strings.Split(area.ConvertFromLtreeFormat(ar.Path), pathSepInService) parentID := allParents[len(allParents)-1] // Only the immediate parent's URL. parentSelfURL := rest.AbsoluteURL(request, app.AreaHref(parentID)) i.Relationships.Parent = &app.RelationGeneric{ Data: &app.GenericData{ Type: &areaType, ID: &parentID, }, Links: &app.GenericLinks{ Self: &parentSelfURL, }, } } for _, add := range additional { add(appl, request, ar, i) } return i }