APP structure
app/
app/
relations/
coffees.rb # TestApp::Relations::Coffees < TestApp::Relation
repositories/
coffee_repo.rb # TestApp::Repositories::CoffeeRepo < TestApp::Repository
structs/
coffee.rb # TestApp::Structs::Coffee < TestApp::Struct
relation.rb # TestApp::Relation < Hanami::Relation
repository.rb # TestApp::Repository < Hanami::Repository
struct.rb # TestApp::Struct < Hanami::Struct
db/
migrations/
schema.rb
slices/
slices/
admin/
relations/
users.rb # Admin::Relations::Coffees < Admin::Relation
repositories/
coffee_repo.rb # Admin::Repositories::CoffeeRepo < Admin::Repository
structs/
coffee.rb # Admin::Structs::Coffee < TestApp::Struct
relation.rb # Admin::Relation < TestApp::Relation
repository.rb # Admin::Repository < TestApp::Repository
struct.rb # Admin::Struct < TestApp::Struct
db/
migrations/
schema.rb
ENV Vars & Settings
-
DATABASE_URL
: App database -
ADMIN_DATABASE_URL
: Admin database
# config/settings.rb
module TestApp
class Settings < Hanami::Settings
setting :database do
setting :url, constructor: Types::String
end
end
end
TestApp.settings.database.url
Note: My suggestion is to use database.url
instead of database_url
to capture the following use case.
setting :database do
setting :host, constructor: Types::String
setting :port, constructor: Types::String
setting :username, constructor: Types::String
setting :password, constructor: Types::String
end
TestApp.settings.database # => { ... } A Hash
TestApp.settings.database.host # => "..." A String
# slices/admin/config/settings.rb
module Admin
class Settings < TestApp::Settings
setting :database do
setting :url, constructor: Types::String
end
end
end
Admin.settings.database.url
CLI
Generators
Model
$ bundle exec hanami generate model book
create app/structs/book.rb
create app/repositories/book_repository.rb
create app/relations/books.rb
create db/migrations/20230213123250_create_books.rb
$ bundle exec hanami generate model book --slice=admin
create slices/admin/structs/book.rb
create slices/admin/repositories/book_repository.rb
create slices/admin/relations/books.rb
create slices/admin/db/migrations/20230213123250_create_books.rb
Migration
$ bundle exec hanami generate migration create_books
create db/migrations/20230213123250_create_books.rb
$ bundle exec hanami generate migration create_books --slice=admin
create slices/admin/db/migrations/20230213123250_create_books.rb
Database
This is a 2.1 proposal
$ bundle exec hanami generate database --slice=admin --url="postgresql://localhost:5432/admin"
add .env # ADMIN_DATABASE_URL="..."
add .env.development # ADMIN_DATABASE_URL="..."
add .env.test # ADMIN_DATABASE_URL="..."
add slices/admin/config/settings.rb # Settings block to match ENV var
create slices/admin/db/schema.rb
create slices/admin/db/migrations/.keep
The option --slice
is mandatory
If --url
is provided, fill in all .env*
files.
If --url
is NOT provided, only add ADMIN_DATABASE_URL
with an empty string
Database
See 1.x commands for reference
Create
$ bundle exec hanami db create # CREATES ALL DATABASES
$ bundle exec hanami db create --database=app # CREATES App (app/) DATABASE
$ bundle exec hanami db create --database=admin # CREATES Admin (slices/admin) DATABASE
Drop
$ bundle exec hanami db drop # DROPS ALL DATABASES
$ bundle exec hanami db drop --database=app # DROPS App (app/) DATABASE
$ bundle exec hanami db drop --database=admin # DROPS Admin (slices/admin) DATABASE
Migrate
$ bundle exec hanami db migrate # MIGRATES ALL DATABASES
$ bundle exec hanami db migrate --database=app # MIGRATES App (app/) DATABASE
$ bundle exec hanami db migrate --database=admin # MIGRATES Admin (slices/admin) DATABASE
Rollback
$ bundle exec hanami db rollback # ROLLS BACK App (app/) DATABASE
$ bundle exec hanami db rollback 3 # ROLLS BACK App (app/) DATABASE
$ bundle exec hanami db rollback --database=app # ROLLS BACK App (app/) DATABASE
$ bundle exec hanami db rollback 3 --database=app # ROLLS BACK App (app/) DATABASE
$ bundle exec hanami db rollback --database=admin # ROLLS BACK Admin (slices/admin) DATABASE
$ bundle exec hanami db rollback 2 --database=admin # ROLLS BACK Admin (slices/admin) DATABASE
Prepare
$ bundle exec hanami db prepare # PREPARES ALL DATABASES
$ bundle exec hanami db prepare --database=app # PREPARES App (app/) DATABASE
$ bundle exec hanami db prepare --database=admin # PREPARES Admin (slices/admin) DATABASE
Apply
$ bundle exec hanami db apply # RUNS FOR ALL DATABASES
$ bundle exec hanami db apply --database=app # RUNS FOR App (app/) DATABASE
It generates db/schema.sql
file
$ bundle exec hanami db apply --database=admin # RUNS FOR Admin (slices/admin) DATABASE
It generates slices/admin/db/schema.sql
file
Version
$ bundle exec hanami db version # PRINTS ALL DATABASES VERSIONS
$ bundle exec hanami db version --database=app # PRINTS App (app/) DATABASE VERSION
$ bundle exec hanami db version --database=admin # PRINTS Admin (slices/admin) DATABASE VERSION
Rake
For compatibility with Ruby hosting vendors, we need to expose a db:migrate
Rake task
$ bundle exec rake db:migrate # MIGRATES ALL THE DATABASES
$ HANAMI_DATABASE=app bundle exec rake db:migrate # MIGRATES App (app/) DATABASE
$ HANAMI_DATABASE=admin bundle exec rake db:migrate # MIGRATES Admin (slices/admin) DATABASE