Skip to content
Permalink
Browse files

Adding episode on Buffalo & Pop for DB Integration (episode 30) (#180)

* Adding episode on Buffalo & Pop for DB Integration (episode 30)

* Rm episode30

Will re-commit the non-submodule version

* Adding code (not versioned) episode30

* Adding the TODO resource

* Adding title to the TODO

* Moar!

* updating README

* Adding page for episode 30

* updating YT embed

Also updating the archetype for that
  • Loading branch information...
arschles committed Aug 29, 2019
1 parent 74d7955 commit 4d1ad68ba6c7b39a9b4749413e0872ae60b2ae97
Showing with 8,254 additions and 1 deletion.
  1. +3 −0 episode30/.babelrc
  2. +21 −0 episode30/.buffalo.dev.yml
  3. +20 −0 episode30/.codeclimate.yml
  4. +3 −0 episode30/.dockerignore
  5. +27 −0 episode30/.gitignore
  6. +35 −0 episode30/Dockerfile
  7. +7 −0 episode30/Makefile
  8. +44 −0 episode30/README.md
  9. +24 −0 episode30/actions/actions_test.go
  10. +93 −0 episode30/actions/app.go
  11. +9 −0 episode30/actions/home.go
  12. +8 −0 episode30/actions/home_test.go
  13. +28 −0 episode30/actions/render.go
  14. +203 −0 episode30/actions/todoes.go
  15. +29 −0 episode30/actions/todoes_test.go
  16. +118 −0 episode30/assets/css/_buffalo.scss
  17. +4 −0 episode30/assets/css/application.scss
  18. BIN episode30/assets/images/favicon.ico
  19. +721 −0 episode30/assets/images/logo.svg
  20. +6 −0 episode30/assets/js/application.js
  21. +13 −0 episode30/config/buffalo-app.toml
  22. +3 −0 episode30/config/buffalo-plugins.toml
  23. +13 −0 episode30/database.yml
  24. +9 −0 episode30/docker-compose.yml
  25. +32 −0 episode30/fixtures/sample.toml
  26. +22 −0 episode30/go.mod
  27. +1,019 −0 episode30/go.sum
  28. +15 −0 episode30/grifts/db.go
  29. +11 −0 episode30/grifts/init.go
  30. +3 −0 episode30/inflections.json
  31. +3 −0 episode30/locales/all.en-us.yaml
  32. +6 −0 episode30/locales/todoes.en-us.yaml
  33. +38 −0 episode30/main.go
  34. +1 −0 episode30/migrations/20190828223015_create_todoes.down.fizz
  35. +4 −0 episode30/migrations/20190828223015_create_todoes.up.fizz
  36. +1 −0 episode30/migrations/20190828223647_title.down.fizz
  37. +1 −0 episode30/migrations/20190828223647_title.up.fizz
  38. +66 −0 episode30/migrations/schema.sql
  39. +22 −0 episode30/models/models.go
  40. +24 −0 episode30/models/models_test.go
  41. +51 −0 episode30/models/todo.go
  42. +7 −0 episode30/models/todo_test.go
  43. +40 −0 episode30/package.json
  44. +2 −0 episode30/public/robots.txt
  45. +14 −0 episode30/templates/_flash.plush.html
  46. +21 −0 episode30/templates/application.plush.html
  47. +64 −0 episode30/templates/index.plush.html
  48. +1 −0 episode30/templates/todoes/_form.html
  49. +1 −0 episode30/templates/todoes/_form.plush.html
  50. +9 −0 episode30/templates/todoes/edit.html
  51. +8 −0 episode30/templates/todoes/edit.plush.html
  52. +34 −0 episode30/templates/todoes/index.html
  53. +33 −0 episode30/templates/todoes/index.plush.html
  54. +9 −0 episode30/templates/todoes/new.html
  55. +8 −0 episode30/templates/todoes/new.plush.html
  56. +21 −0 episode30/templates/todoes/show.html
  57. +18 −0 episode30/templates/todoes/show.plush.html
  58. +112 −0 episode30/webpack.config.js
  59. +5,069 −0 episode30/yarn.lock
  60. +1 −1 www/archetypes/screencast.md
  61. +22 −0 www/content/screencast/episode_30_buffalo_pop_basics.md
@@ -0,0 +1,3 @@
{
"presets": ["@babel/preset-env"]
}
@@ -0,0 +1,21 @@
app_root: .
ignored_folders:
- vendor
- log
- logs
- assets
- public
- grifts
- tmp
- bin
- node_modules
- .sass-cache
included_extensions:
- .go
- .env
build_path: tmp
build_delay: 200ns
binary_name: episode30-build
command_flags: []
enable_colors: true
log_name: buffalo
@@ -0,0 +1,20 @@
engines:
fixme:
enabled: true
gofmt:
enabled: true
golint:
enabled: true
govet:
enabled: true
exclude_paths:
- grifts/**/*
- "**/*_test.go"
- "*_test.go"
- "**_test.go"
- logs/*
- public/*
- templates/*
ratings:
paths:
- "**.go"
@@ -0,0 +1,3 @@
node_modules/
*.log
bin/
@@ -0,0 +1,27 @@
vendor/
**/*.log
**/*.sqlite
.idea/
bin/
tmp/
node_modules/
.sass-cache/
*-packr.go
public/assets/
.vscode/
.grifter/
.env
**/.DS_Store
*.pid
coverage
coverage.data
.svn
.console_history
.sass-cache/*
.jhw-cache/
jhw.*
*.sublime*
node_modules/
dist/
generated/
.vendor/
@@ -0,0 +1,35 @@
# This is a multi-stage Dockerfile and requires >= Docker 17.05
# https://docs.docker.com/engine/userguide/eng-image/multistage-build/
FROM gobuffalo/buffalo:v0.14.8 as builder

RUN mkdir -p $GOPATH/src/episode30
WORKDIR $GOPATH/src/episode30

# this will cache the npm install step, unless package.json changes
ADD package.json .
ADD yarn.lock .
RUN yarn install --no-progress
ADD . .
ENV GO111MODULES=on
RUN go get ./...
RUN buffalo build --static -o /bin/app

FROM alpine
RUN apk add --no-cache bash
RUN apk add --no-cache ca-certificates

WORKDIR /bin/

COPY --from=builder /bin/app .

# Uncomment to run the binary in "production" mode:
# ENV GO_ENV=production

# Bind the app to 0.0.0.0 so it can be seen from outside the container
ENV ADDR=0.0.0.0

EXPOSE 3000

# Uncomment to run the migrations before running the binary:
# CMD /bin/app migrate; /bin/app
CMD exec /bin/app
@@ -0,0 +1,7 @@
.PHONY: start-db
start-db:
docker-compose -p ep30 up -d dev-env

.PHONY: stop-db
stop-db:
docker-compose -p ep30 down
@@ -0,0 +1,44 @@
# Hooking your Buffalo Webapp to a Database

Go in 5 Minutes, episode 30.

Another episode in the [Buffalo](https://gobuffalo.io) series! [Last episode](https://gifm.dev/screencast/episode_29_buffalo_login_with_github_using_goth/), we talked about building a "login with GitHub" button into your Buffalo app.

Today, we're gonna travel from that part of your app up to the database layer. If you're building a website, you'll almost certainly need a database to store information about your users. Luckily, Buffalo has great support for some of the most popular SQL databases.

>This episode is tangentially related to [#168](https://github.com/arschles/go-in-5-minutes/issues/168)
We're going to use the [pop](https://github.com/gobuffalo/pop) library -- which has great Buffalo integration -- to do some basic database integration in our app.

I'll briefly introduce the library and how to use it, then we'll go right to the code and see it in action!

Check out the screencast for more!

## How To Run The App

This is a standard Buffalo app that requires a PostgresDB server to be running locally (on `127.0.0.1`). Here's what you need to do to run the app.

First, run the database. We've provided a [Docker Compose](https://docs.docker.com/compose/) configuration file, so the easiest way to do this is to download the `docker-compose` binary and ensure you have the [Docker](https://docs.docker.com/install/) server running. After you have those dependencies, run the database:

```console
$ docker-compose -p ep30 up -d dev-env
```

This starts the database in a container in the background. Next, you should be all set to run the app:

```console
$ buffalo dev
```

Now, you can access the app on `http://localhost:3000`.

When you're done, clean up the database with this command:

```console
$ docker-compose -p ep30 down
```

# Show Notes

- [Buffalo docs on database interaction](https://gobuffalo.io/en/docs/db/getting-started/)
- [The pop repository on GitHub](https://github.com/gobuffalo/pop)
@@ -0,0 +1,24 @@
package actions

import (
"testing"

"github.com/gobuffalo/packr/v2"
"github.com/gobuffalo/suite"
)

type ActionSuite struct {
*suite.Action
}

func Test_ActionSuite(t *testing.T) {
action, err := suite.NewActionWithFixtures(App(), packr.New("Test_ActionSuite", "../fixtures"))
if err != nil {
t.Fatal(err)
}

as := &ActionSuite{
Action: action,
}
suite.Run(t, as)
}
@@ -0,0 +1,93 @@
package actions

import (
"github.com/gobuffalo/buffalo"
"github.com/gobuffalo/envy"
forcessl "github.com/gobuffalo/mw-forcessl"
paramlogger "github.com/gobuffalo/mw-paramlogger"
"github.com/unrolled/secure"

"github.com/arschles/go-in-5-minutes/episode30/models"

"github.com/gobuffalo/buffalo-pop/pop/popmw"
csrf "github.com/gobuffalo/mw-csrf"
i18n "github.com/gobuffalo/mw-i18n"
"github.com/gobuffalo/packr/v2"
)

// ENV is used to help switch settings based on where the
// application is being run. Default is "development".
var ENV = envy.Get("GO_ENV", "development")
var app *buffalo.App
var T *i18n.Translator

// App is where all routes and middleware for buffalo
// should be defined. This is the nerve center of your
// application.
//
// Routing, middleware, groups, etc... are declared TOP -> DOWN.
// This means if you add a middleware to `app` *after* declaring a
// group, that group will NOT have that new middleware. The same
// is true of resource declarations as well.
//
// It also means that routes are checked in the order they are declared.
// `ServeFiles` is a CATCH-ALL route, so it should always be
// placed last in the route declarations, as it will prevent routes
// declared after it to never be called.
func App() *buffalo.App {
if app == nil {
app = buffalo.New(buffalo.Options{
Env: ENV,
SessionName: "_episode30_session",
})

// Automatically redirect to SSL
app.Use(forceSSL())

// Log request parameters (filters apply).
app.Use(paramlogger.ParameterLogger)

// Protect against CSRF attacks. https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
// Remove to disable this.
app.Use(csrf.New)

// Wraps each request in a transaction.
// c.Value("tx").(*pop.Connection)
// Remove to disable this.
app.Use(popmw.Transaction(models.DB))

// Setup and use translations:
app.Use(translations())

app.GET("/", HomeHandler)

app.Resource("/todoes", TodoesResource{})
app.ServeFiles("/", assetsBox) // serve files from the public directory
}

return app
}

// translations will load locale files, set up the translator `actions.T`,
// and will return a middleware to use to load the correct locale for each
// request.
// for more information: https://gobuffalo.io/en/docs/localization
func translations() buffalo.MiddlewareFunc {
var err error
if T, err = i18n.New(packr.New("app:locales", "../locales"), "en-US"); err != nil {
app.Stop(err)
}
return T.Middleware()
}

// forceSSL will return a middleware that will redirect an incoming request
// if it is not HTTPS. "http://example.com" => "https://example.com".
// This middleware does **not** enable SSL. for your application. To do that
// we recommend using a proxy: https://gobuffalo.io/en/docs/proxy
// for more information: https://github.com/unrolled/secure/
func forceSSL() buffalo.MiddlewareFunc {
return forcessl.Middleware(secure.Options{
SSLRedirect: ENV == "production",
SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"},
})
}
@@ -0,0 +1,9 @@
package actions

import "github.com/gobuffalo/buffalo"

// HomeHandler is a default handler to serve up
// a home page.
func HomeHandler(c buffalo.Context) error {
return c.Render(200, r.HTML("index.html"))
}
@@ -0,0 +1,8 @@
package actions

func (as *ActionSuite) Test_HomeHandler() {
res := as.HTML("/").Get()

as.Equal(200, res.Code)
as.Contains(res.Body.String(), "Welcome to Buffalo")
}
@@ -0,0 +1,28 @@
package actions

import (
"github.com/gobuffalo/buffalo/render"
"github.com/gobuffalo/packr/v2"
)

var r *render.Engine
var assetsBox = packr.New("app:assets", "../public")

func init() {
r = render.New(render.Options{
// HTML layout to be used for all HTML requests:
HTMLLayout: "application.plush.html",

// Box containing all of the templates:
TemplatesBox: packr.New("app:templates", "../templates"),
AssetsBox: assetsBox,

// Add template helpers here:
Helpers: render.Helpers{
// for non-bootstrap form helpers uncomment the lines
// below and import "github.com/gobuffalo/helpers/forms"
// forms.FormKey: forms.Form,
// forms.FormForKey: forms.FormFor,
},
})
}

0 comments on commit 4d1ad68

Please sign in to comment.
You can’t perform that action at this time.