Skip to content
This repository has been archived by the owner on Feb 24, 2024. It is now read-only.

Commit

Permalink
Merge branch '365-resource-generator-json' of https://github.com/stan…
Browse files Browse the repository at this point in the history
…islas-m/buffalo into stanislas-m-365-resource-generator-json
  • Loading branch information
markbates committed Apr 16, 2017
2 parents 1ccf694 + d94f65e commit f36e131
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 9 deletions.
8 changes: 8 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ RUN buffalo build
RUN buffalo g resource users name:text email:text
RUN filetest -c $GOPATH/src/github.com/gobuffalo/buffalo/buffalo/cmd/filetests/resource_model_migration.json

RUN rm models/user_test.go
RUN rm models/user.go
RUN rm actions/users_test.go
RUN rm -rv templates/users

RUN buffalo g resource --type=json users name:text email:text
RUN filetest -c $GOPATH/src/github.com/gobuffalo/buffalo/buffalo/cmd/filetests/resource_json.json

RUN rm models/user_test.go
RUN rm models/user.go
RUN rm actions/users_test.go
Expand Down
20 changes: 20 additions & 0 deletions buffalo/cmd/filetests/resource_json.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[{
"path": "templates/users/_form.html",
"absent": true
},
{
"path": "templates/users/edit.html",
"absent": true
},
{
"path": "templates/users/index.html",
"absent": true
},
{
"path": "templates/users/new.html",
"absent": true
},
{
"path": "templates/users/show.html",
"absent": true
}]
1 change: 1 addition & 0 deletions buffalo/cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func init() {
generate.ResourceCmd.Flags().BoolVarP(&generate.SkipResourceMigration, "skip-migration", "s", false, "sets resource generator not-to add model migration")
generate.ResourceCmd.Flags().BoolVarP(&generate.SkipResourceModel, "skip-model", "", false, "makes resource generator not to generate model nor migrations")
generate.ResourceCmd.Flags().StringVarP(&generate.UseResourceModel, "use-model", "u", "", "generates crud options for a model")
generate.ResourceCmd.Flags().StringVarP(&generate.ResourceMimeType, "type", "", "html", "sets the resource type (html or json)")

RootCmd.AddCommand(generateCmd)
}
9 changes: 9 additions & 0 deletions buffalo/cmd/generate/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ var SkipResourceModel = false
// UseResourceModel allows to generate a resource with a working model.
var UseResourceModel = ""

// ResourceMimeType allows to generate a typed resource (HTML by default, JSON...).
var ResourceMimeType = "html"

// ResourceCmd generates a new actions/resource file and a stub test.
var ResourceCmd = &cobra.Command{
Use: "resource [name]",
Expand Down Expand Up @@ -81,6 +84,11 @@ var ResourceCmd = &cobra.Command{
modelName = name
}
}

if ResourceMimeType != "html" && ResourceMimeType != "json" {
return errors.New("invalid resource type, you need to choose between \"html\" and \"json\"")
}

modelProps := getModelPropertiesFromArgs(args)

data := makr.Data{
Expand All @@ -106,6 +114,7 @@ var ResourceCmd = &cobra.Command{
"skipMigration": SkipResourceMigration,
"skipModel": SkipResourceModel,
"useModel": UseResourceModel,
"mimeType": ResourceMimeType,
}
g, err := resource.New(data)
if err != nil {
Expand Down
23 changes: 14 additions & 9 deletions generators/resource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,30 @@ func New(data makr.Data) (*makr.Generator, error) {
// Get the flags
useModel := data["useModel"].(string)
skipModel := data["skipModel"].(bool)
mimeType := data["mimeType"].(string)

tmplName := "resource-use_model"

if skipModel == true {
if mimeType == "json" {
tmplName = "resource-json"
} else if skipModel == true {
tmplName = "resource-name"
}
for _, f := range files {
// Adding the resource template to the generator
if strings.Contains(f.WritePath, tmplName) {
g.Add(makr.NewFile(strings.Replace(f.WritePath, tmplName, data["under"].(string), -1), f.Body))
}
// Adding the html templates to the generator
if strings.Contains(f.WritePath, "model-view-") {
targetPath := filepath.Join(
filepath.Dir(f.WritePath),
data["modelPluralUnder"].(string),
strings.Replace(filepath.Base(f.WritePath), "model-view-", "", -1),
)
g.Add(makr.NewFile(targetPath, f.Body))
if mimeType == "html" {
// Adding the html templates to the generator
if strings.Contains(f.WritePath, "model-view-") {
targetPath := filepath.Join(
filepath.Dir(f.WritePath),
data["modelPluralUnder"].(string),
strings.Replace(filepath.Base(f.WritePath), "model-view-", "", -1),
)
g.Add(makr.NewFile(targetPath, f.Body))
}
}
}
g.Add(&makr.Func{
Expand Down
141 changes: 141 additions & 0 deletions generators/resource/templates/actions/resource-json.go.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package actions

import (
"errors"

"github.com/gobuffalo/buffalo"
"github.com/markbates/pop"
"{{.modelsPath}}"
)

// This file is generated by Buffalo. It offers a basic structure for
// adding, editing and deleting a page. If your model is more
// complex or you need more than the basic implementation you need to
// edit this file.

// Following naming logic is implemented in Buffalo:
// Model: Singular ({{.model}})
// DB Table: Plural ({{.modelPlural}})
// Resource: Plural ({{.modelPlural}})
// Path: Plural (/{{.under}})

// {{.modelPlural}}Resource is the resource for the {{.singular}} model
type {{.camel}}Resource struct{
buffalo.Resource
}

// List gets all {{.modelPlural}}. This function is mapped to the the path
// GET /{{.under}}
func (v {{.camel}}Resource) List(c buffalo.Context) error {
// Get the DB connection from the context
tx := c.Value("tx").(*pop.Connection)
{{.varPlural}} := &models.{{.modelPlural}}{}
// You can order your list here. Just change
err := tx.All({{.varPlural}})
// to:
// err := tx.Order("(case when completed then 1 else 2 end) desc, lower([sort_parameter]) asc").All({{.downFirstCap}})
// Don't forget to change [sort_parameter] to the parameter of
// your model, which should be used for sorting.
if err != nil {
return err
}
return c.Render(200, r.JSON({{.varPlural}}))
}

// Show gets the data for one {{.model}}. This function is mapped to
// the path GET /{{.under}}/{{"{"}}{{.underSingular}}_id}
func (v {{.camel}}Resource) Show(c buffalo.Context) error {
// Get the DB connection from the context
tx := c.Value("tx").(*pop.Connection)
// Allocate an empty {{.model}}
{{.varSingular}} := &models.{{.model}}{}
// To find the {{.model}} the parameter {{.underSingular}}_id is used.
err := tx.Find({{.varSingular}}, c.Param("{{.underSingular}}_id"))
if err != nil {
return err
}
return c.Render(200, r.JSON({{.varSingular}}))
}

// New default implementation. Returns a 404
func (v {{.camel}}Resource) New(c buffalo.Context) error {
return c.Error(404, errors.New("not available"))
}

// Create adds a {{.singular}} to the DB. This function is mapped to the
// path POST /{{.under}}
func (v {{.camel}}Resource) Create(c buffalo.Context) error {
// Allocate an empty {{.model}}
{{.varSingular}} := &models.{{.model}}{}
// Bind {{.varSingular}} to the html form elements
err := c.Bind({{.varSingular}})
if err != nil {
return err
}
// Get the DB connection from the context
tx := c.Value("tx").(*pop.Connection)
// Validate the data from the html form
verrs, err := tx.ValidateAndCreate({{.varSingular}})
if err != nil {
return err
}
if verrs.HasAny() {
// Render errors as JSON
return c.Render(400, r.JSON(verrs))
}
// Success!
return c.Render(201, nil)
}

// Edit default implementation. Returns a 404
func (v {{.camel}}Resource) Edit(c buffalo.Context) error {
return c.Error(404, errors.New("not available"))
}

// Update changes a {{.singular}} in the DB. This function is mapped to
// the path PUT /{{.under}}/{{"{"}}{{.underSingular}}_id}
func (v {{.camel}}Resource) Update(c buffalo.Context) error {
// Get the DB connection from the context
tx := c.Value("tx").(*pop.Connection)
// Allocate an empty {{.model}}
{{.varSingular}} := &models.{{.model}}{}
err := tx.Find({{.varSingular}}, c.Param("{{.underSingular}}_id"))
if err != nil {
return err
}
// Bind {{.singular}} to the html form elements
err = c.Bind({{.varSingular}})
if err != nil {
return err
}
verrs, err := tx.ValidateAndUpdate({{.varSingular}})
if err != nil {
return err
}
if verrs.HasAny() {
// Render errors as JSON
return c.Render(400, r.JSON(verrs))
}
// Success!
return c.Render(200, nil)
}

// Destroy deletes a {{.singular}} from the DB. This function is mapped
// to the path DELETE /{{.under}}/{{"{"}}{{.underSingular}}_id}
func (v {{.camel}}Resource) Destroy(c buffalo.Context) error {
// Get the DB connection from the context
tx := c.Value("tx").(*pop.Connection)
// Allocate an empty {{.model}}
{{.varSingular}} := &models.{{.model}}{}
// To find the {{.model}} the parameter {{.underSingular}}_id is used.
err := tx.Find({{.varSingular}}, c.Param("{{.underSingular}}_id"))
if err != nil {
return err
}
err = tx.Destroy({{.varSingular}})
if err != nil {
return err
}
// Success!
return c.Render(200, nil)
}
12 changes: 12 additions & 0 deletions generators/resource/templates/actions/resource-json_test.go.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package actions_test

import (
"testing"

"github.com/stretchr/testify/require"
)
{{ range $a := .actions }}
func (as *ActionSuite) Test_{{$.camel}}Resource_{{ camelize $a }}() {
as.Fail("Not Implemented!")
}
{{ end }}

0 comments on commit f36e131

Please sign in to comment.