livebud / bud

The Full-Stack Web Framework for Go
MIT License
5.58k stars 178 forks source link

Bud new model #238

Open JusticeN opened 2 years ago

JusticeN commented 2 years ago

Is there a plan to have a command for generating models and connecting it with database?

Bishwas-py commented 2 years ago

Yupp, that'll be a lot awesome...

matthewmueller commented 2 years ago

Hey folks, thanks for your interest in Bud! We're working on adding built-in model support, but in the meantime, you can do this today yourself.

Conceptually, take a look at the Dependency Injection docs to see how you can bring models into your controllers. Then you can take a look at a real-world example using xo in this https://github.com/vito/bass-loop.

Let me know if you have any questions!

JusticeN commented 2 years ago

Thank you really good example.

I was thinking about something like the ruby and rails model field generator from the cli.

Or the jhipster one for generating Java spring boot apps.

Or may be "bud" just have a different philosophy

matthewmueller commented 2 years ago

We definitely want to have a Rails-like model generator once we have model support. The philosophy is similar here.

I hadn't heard of jhipster, I'll check that one out, thanks for sharing!

Bishwas-py commented 1 year ago

We definitely want to have a Rails-like model generator once we have model support. The philosophy is similar here.

I hadn't heard of jhipster, I'll check that one out, thanks for sharing!

We got the model?

preslavrachev commented 1 year ago

@matthewmueller I am a fan of SQLBoiler. I suppose it will work just the same, correct? I can simply generate my models and use the dependency injection to pass a sql.DB connection to all my controllers.

matthewmueller commented 1 year ago

Yep, that would work! You might just need to wrap it to tell Bud how to initialize it. I usually put these wrappers in internal, but it doesn't really matter.

Perhaps in internal/postgres/postgres.go (untested):

package postgres

import "database/sql"

func Open() (*DB, error) {
  // Open handle to database like normal
  return sql.Open("postgres", "dbname=fun user=abc")
}

type DB = sql.DB

The type alias is to make sure dependency injection uses this file to initialize *sql.DB. Then from the controllers, you can do:

package users

import "app.com/internal/postgres"

type Controller struct {
  DB *postgres.DB
}

func (c *Controller) Index(ctx context.Context) error {
  // Query all users
  users, err := models.Users().All(ctx, c.DB)
  // ...
}

You can also couple it with an environment parser like https://github.com/caarlos0/env to be able to set this config programmatically:

import "app.com/internal/env"

func Open(env *env.Env) (*sql.DB, error) {
  // Open handle to database like normal
  return sql.Open(env.Database.Name, env.Database.URL)
}

Then in say internal/env/env.go (untested):

package env

import "https://github.com/caarlos0/env"

type Env struct {
  Database Database
}

type Database struct {
  Name string `env:"DATABASE_NAME"`
  URL string `env:"DATABASE_URL"`
}

func Parse() (*Env, error) {
  var e Env
  if err :=  env.Parse(&e); err != nil {
    return nil, err
  }
  return &e, nil
}