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

Commit

Permalink
just support potatoes using flect (#1440)
Browse files Browse the repository at this point in the history
  • Loading branch information
sio4 committed Nov 13, 2018
1 parent af44985 commit a19f4e8
Show file tree
Hide file tree
Showing 15 changed files with 165 additions and 147 deletions.
4 changes: 2 additions & 2 deletions buffalo/cmd/generate/resource.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package generate

import (
"github.com/markbates/inflect"
"github.com/pkg/errors"

"github.com/gobuffalo/buffalo/generators/resource"
"github.com/gobuffalo/flect/name"
"github.com/gobuffalo/makr"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -36,7 +36,7 @@ var ResourceCmd = &cobra.Command{
o.SkipTemplates = resourceOptions.SkipTemplates
if resourceOptions.ModelName != "" {
o.UseModel = true
o.Model = inflect.Name(resourceOptions.ModelName)
o.Model = name.New(resourceOptions.ModelName)
}

if err := o.Validate(); err != nil {
Expand Down
16 changes: 8 additions & 8 deletions generators/resource/a_resource-packr.go

Large diffs are not rendered by default.

43 changes: 22 additions & 21 deletions generators/resource/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,24 @@ import (
"os"
"strings"

"github.com/gobuffalo/flect"
"github.com/gobuffalo/flect/name"
"github.com/gobuffalo/meta"
"github.com/markbates/inflect"
)

// Generator for generating a new resource
type Generator struct {
App meta.App `json:"app"`
Name inflect.Name `json:"name"`
Model inflect.Name `json:"model"`
SkipMigration bool `json:"skip_migration"`
SkipModel bool `json:"skip_model"`
SkipTemplates bool `json:"skip_templates"`
UseModel bool `json:"use_model"`
FilesPath string `json:"files_path"`
ActionsPath string `json:"actions_path"`
Props []Prop `json:"props"`
Args []string `json:"args"`
App meta.App `json:"app"`
Name name.Ident `json:"name"`
Model name.Ident `json:"model"`
SkipMigration bool `json:"skip_migration"`
SkipModel bool `json:"skip_model"`
SkipTemplates bool `json:"skip_templates"`
UseModel bool `json:"use_model"`
FilesPath string `json:"files_path"`
ActionsPath string `json:"actions_path"`
Props []Prop `json:"props"`
Args []string `json:"args"`
}

// New constructs new options for generating a resource
Expand All @@ -33,27 +34,27 @@ func New(modelName string, args ...string) (Generator, error) {
o.App = meta.New(pwd)

if len(o.Args) > 0 {
o.Name = inflect.Name(o.Args[0])
o.Model = inflect.Name(o.Args[0])
o.Name = name.New(flect.Singularize(o.Args[0]))
o.Model = o.Name
}
o.Props = modelPropertiesFromArgs(o.Args)

o.FilesPath = o.Name.PluralUnder()
o.FilesPath = o.Name.File().Pluralize().String()
o.ActionsPath = o.FilesPath
if strings.Contains(string(o.Name), "/") {
parts := strings.Split(string(o.Name), "/")
o.Model = inflect.Name(parts[len(parts)-1])
o.ActionsPath = inflect.Underscore(o.Name.Resource())
if strings.Contains(o.Name.String(), "/") {
parts := strings.Split(o.Name.String(), "/")
o.Model = name.New(parts[len(parts)-1])
o.ActionsPath = o.Name.Resource().Underscore().String()
}
if modelName != "" {
o.Model = inflect.Name(modelName)
o.Model = name.New(modelName)
}
return o, o.Validate()
}

// Validate that the options have what you need to build a new resource
func (o Generator) Validate() error {
if len(o.Args) == 0 && o.Model == "" {
if len(o.Args) == 0 && o.Model.String() == "" {
return errors.New("you must specify a resource name")
}
return nil
Expand Down
20 changes: 19 additions & 1 deletion generators/resource/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,23 @@ func Test_New_WithNestedName(t *testing.T) {
g, err := New("", "admin/user")
r.NoError(err)
name := g.Name
r.Equal("admin_user_id", name.ParamID())
r.Equal("admin_user_id", name.ParamID().String())
}

func Test_New_WithNestedName_Plural(t *testing.T) {
r := require.New(t)

g, err := New("", "admin/users")
r.NoError(err)
name := g.Name
r.Equal("admin_user_id", name.ParamID().String())
}

func Test_New_FilesPath_WithNestedName(t *testing.T) {
r := require.New(t)

g, err := New("", "Admin/superFast/Plane")
r.NoError(err)
r.Equal("admin/super_fast/planes", g.FilesPath)
r.Equal("admin_super_fast_planes", g.ActionsPath)
}
2 changes: 1 addition & 1 deletion generators/resource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func (res Generator) Run(root string, data makr.Data) error {
func (res Generator) modelCommand() makr.Command {
args := res.Args
args = append(args[:0], args[0+1:]...)
args = append([]string{"db", "g", "model", res.Model.UnderSingular()}, args...)
args = append([]string{"db", "g", "model", res.Model.Singularize().Underscore().String()}, args...)

if res.SkipMigration {
args = append(args, "--skip-migration")
Expand Down
68 changes: 34 additions & 34 deletions generators/resource/templates/actions/resource-json-xml.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ import (
// edit this file.

// Following naming logic is implemented in Buffalo:
// Model: Singular ({{.opts.Model.Model}})
// DB Table: Plural ({{.opts.Model.Table}})
// Model: Singular ({{.opts.Model.Proper}})
// DB Table: Plural ({{.opts.Model.Tableize}})
// Resource: Plural ({{.opts.Name.Resource}})
// Path: Plural (/{{.opts.Name.URL}})
// View Template Folder: Plural (/templates/{{.opts.FilesPath}}/)

// {{.opts.Name.Resource}}Resource is the resource for the {{.opts.Model.Model}} model
// {{.opts.Name.Resource}}Resource is the resource for the {{.opts.Model.Proper}} model
type {{.opts.Name.Resource}}Resource struct{
buffalo.Resource
}

// List gets all {{.opts.Model.ModelPlural}}. This function is mapped to the path
// List gets all {{.opts.Model.Group}}. This function is mapped to the path
// GET /{{.opts.Name.URL}}
func (v {{.opts.Name.Resource}}Resource) List(c buffalo.Context) error {
// Get the DB connection from the context
Expand All @@ -34,13 +34,13 @@ func (v {{.opts.Name.Resource}}Resource) List(c buffalo.Context) error {
return errors.WithStack(errors.New("no transaction found"))
}

{{.opts.Model.VarCasePlural}} := &models.{{.opts.Model.ModelPlural}}{}
{{.opts.Model.VarCasePlural}} := &models.{{.opts.Model.Group}}{}

// Paginate results. Params "page" and "per_page" control pagination.
// Default values are "page=1" and "per_page=20".
q := tx.PaginateFromParams(c.Params())

// Retrieve all {{.opts.Model.ModelPlural}} from the DB
// Retrieve all {{.opts.Model.Group}} from the DB
if err := q.All({{.opts.Model.VarCasePlural}}); err != nil {
return errors.WithStack(err)
}
Expand All @@ -51,7 +51,7 @@ func (v {{.opts.Name.Resource}}Resource) List(c buffalo.Context) error {
return c.Render(200, r.{{.opts.MimeType}}({{.opts.Model.VarCasePlural}}))
}

// Show gets the data for one {{.opts.Model.Model}}. This function is mapped to
// Show gets the data for one {{.opts.Model.Proper}}. This function is mapped to
// the path GET /{{.opts.Name.URL}}/{{"{"}}{{.opts.Name.ParamID}}}
func (v {{.opts.Name.Resource}}Resource) Show(c buffalo.Context) error {
// Get the DB connection from the context
Expand All @@ -60,30 +60,30 @@ func (v {{.opts.Name.Resource}}Resource) Show(c buffalo.Context) error {
return errors.WithStack(errors.New("no transaction found"))
}

// Allocate an empty {{.opts.Model.Model}}
{{.opts.Model.VarCaseSingular}} := &models.{{.opts.Model.Model}}{}
// Allocate an empty {{.opts.Model.Proper}}
{{.opts.Model.VarCaseSingle}} := &models.{{.opts.Model.Proper}}{}

// To find the {{.opts.Model.Model}} the parameter {{.opts.Name.ParamID}} is used.
if err := tx.Find({{.opts.Model.VarCaseSingular}}, c.Param("{{.opts.Name.ParamID}}")); err != nil {
// To find the {{.opts.Model.Proper}} the parameter {{.opts.Name.ParamID}} is used.
if err := tx.Find({{.opts.Model.VarCaseSingle}}, c.Param("{{.opts.Name.ParamID}}")); err != nil {
return c.Error(404, err)
}

return c.Render(200, r.{{.opts.MimeType}}({{.opts.Model.VarCaseSingular}}))
return c.Render(200, r.{{.opts.MimeType}}({{.opts.Model.VarCaseSingle}}))
}

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

// Create adds a {{.opts.Model.Model}} to the DB. This function is mapped to the
// Create adds a {{.opts.Model.Proper}} to the DB. This function is mapped to the
// path POST /{{.opts.Name.URL}}
func (v {{.opts.Name.Resource}}Resource) Create(c buffalo.Context) error {
// Allocate an empty {{.opts.Model.Model}}
{{.opts.Model.VarCaseSingular}} := &models.{{.opts.Model.Model}}{}
// Allocate an empty {{.opts.Model.Proper}}
{{.opts.Model.VarCaseSingle}} := &models.{{.opts.Model.Proper}}{}

// Bind {{.opts.Model.VarCaseSingular}} to the html form elements
if err := c.Bind({{.opts.Model.VarCaseSingular}}); err != nil {
// Bind {{.opts.Model.VarCaseSingle}} to the html form elements
if err := c.Bind({{.opts.Model.VarCaseSingle}}); err != nil {
return errors.WithStack(err)
}

Expand All @@ -94,7 +94,7 @@ func (v {{.opts.Name.Resource}}Resource) Create(c buffalo.Context) error {
}

// Validate the data from the html form
verrs, err := tx.ValidateAndCreate({{.opts.Model.VarCaseSingular}})
verrs, err := tx.ValidateAndCreate({{.opts.Model.VarCaseSingle}})
if err != nil {
return errors.WithStack(err)
}
Expand All @@ -104,15 +104,15 @@ func (v {{.opts.Name.Resource}}Resource) Create(c buffalo.Context) error {
return c.Render(400, r.{{.opts.MimeType}}(verrs))
}

return c.Render(201, r.{{.opts.MimeType}}({{.opts.Model.VarCaseSingular}}))
return c.Render(201, r.{{.opts.MimeType}}({{.opts.Model.VarCaseSingle}}))
}

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

// Update changes a {{.opts.Model.Model}} in the DB. This function is mapped to
// Update changes a {{.opts.Model.Proper}} in the DB. This function is mapped to
// the path PUT /{{.opts.Name.URL}}/{{"{"}}{{.opts.Name.ParamID}}}
func (v {{.opts.Name.Resource}}Resource) Update(c buffalo.Context) error {
// Get the DB connection from the context
Expand All @@ -121,19 +121,19 @@ func (v {{.opts.Name.Resource}}Resource) Update(c buffalo.Context) error {
return errors.WithStack(errors.New("no transaction found"))
}

// Allocate an empty {{.opts.Model.Model}}
{{.opts.Model.VarCaseSingular}} := &models.{{.opts.Model.Model}}{}
// Allocate an empty {{.opts.Model.Proper}}
{{.opts.Model.VarCaseSingle}} := &models.{{.opts.Model.Proper}}{}

if err := tx.Find({{.opts.Model.VarCaseSingular}}, c.Param("{{.opts.Name.ParamID}}")); err != nil {
if err := tx.Find({{.opts.Model.VarCaseSingle}}, c.Param("{{.opts.Name.ParamID}}")); err != nil {
return c.Error(404, err)
}

// Bind {{.opts.Model.Model}} to the html form elements
if err := c.Bind({{.opts.Model.VarCaseSingular}}); err != nil {
// Bind {{.opts.Model.Proper}} to the html form elements
if err := c.Bind({{.opts.Model.VarCaseSingle}}); err != nil {
return errors.WithStack(err)
}

verrs, err := tx.ValidateAndUpdate({{.opts.Model.VarCaseSingular}})
verrs, err := tx.ValidateAndUpdate({{.opts.Model.VarCaseSingle}})
if err != nil {
return errors.WithStack(err)
}
Expand All @@ -143,10 +143,10 @@ func (v {{.opts.Name.Resource}}Resource) Update(c buffalo.Context) error {
return c.Render(400, r.{{.opts.MimeType}}(verrs))
}

return c.Render(200, r.{{.opts.MimeType}}({{.opts.Model.VarCaseSingular}}))
return c.Render(200, r.{{.opts.MimeType}}({{.opts.Model.VarCaseSingle}}))
}

// Destroy deletes a {{.opts.Model.Model}} from the DB. This function is mapped
// Destroy deletes a {{.opts.Model.Proper}} from the DB. This function is mapped
// to the path DELETE /{{.opts.Name.URL}}/{{"{"}}{{.opts.Name.ParamID}}}
func (v {{.opts.Name.Resource}}Resource) Destroy(c buffalo.Context) error {
// Get the DB connection from the context
Expand All @@ -155,17 +155,17 @@ func (v {{.opts.Name.Resource}}Resource) Destroy(c buffalo.Context) error {
return errors.WithStack(errors.New("no transaction found"))
}

// Allocate an empty {{.opts.Model.Model}}
{{.opts.Model.VarCaseSingular}} := &models.{{.opts.Model.Model}}{}
// Allocate an empty {{.opts.Model.Proper}}
{{.opts.Model.VarCaseSingle}} := &models.{{.opts.Model.Proper}}{}

// To find the {{.opts.Model.Model}} the parameter {{.opts.Name.ParamID}} is used.
if err := tx.Find({{.opts.Model.VarCaseSingular}}, c.Param("{{.opts.Name.ParamID}}")); err != nil {
// To find the {{.opts.Model.Proper}} the parameter {{.opts.Name.ParamID}} is used.
if err := tx.Find({{.opts.Model.VarCaseSingle}}, c.Param("{{.opts.Name.ParamID}}")); err != nil {
return c.Error(404, err)
}

if err := tx.Destroy({{.opts.Model.VarCaseSingular}}); err != nil {
if err := tx.Destroy({{.opts.Model.VarCaseSingle}}); err != nil {
return errors.WithStack(err)
}

return c.Render(200, r.{{.opts.MimeType}}({{.opts.Model.VarCaseSingular}}))
return c.Render(200, r.{{.opts.MimeType}}({{.opts.Model.VarCaseSingle}}))
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type {{.opts.Name.Resource}}Resource struct{
{{ range $a := .actions }}
// {{$a}} default implementation.
func (v {{$.opts.Name.Resource}}Resource) {{$a}}(c buffalo.Context) error {
return c.Render(200, r.String("{{$.opts.Model.Model}}#{{$a}}"))
return c.Render(200, r.String("{{$.opts.Model.Proper}}#{{$a}}"))
}

{{end}}
Loading

0 comments on commit a19f4e8

Please sign in to comment.