We’re back to round out the brand new database layer we introduced in our previous beta release. This time around, we’re adding MySQL, introducing a powerful new way of working with multiple databases, and bringing you a little treat at the same time: full validation contract support in actions!
MySQL support
Now you can generate a new Hanami app with hanami new my_app --database=mysql
and have a ready-to-go MySQL-backed Hanami app! All hanami db
commands (like db prepare
, db migrate
, etc.) have been updated to manage your MySQL database over the lifecycle of your app.
Multiple gateways
With beta1, we introduced the idea of distinct databases per slice. Now with beta2, you can mix and match multiple databases within any slice! This comes courtesy of ROM’s gateways, which you can now setup as part of Hanami’s database layer.
Gateways in ROM represent a connection to a distinct database. You can use them within your relations by declaring a gateway
:
module MyApp
module Relations
class Uploads < MyApp::DB::Relation
# Use the `uploads` table from the `:artifacts` gateway.
gateway :artifacts
schema :uploads, infer: true
end
end
end
By using gateways via relations, you can have your database layer seamlessly work with data from multiple sources, all while maintaining a streamlined public interface via your repos.
You can configure multiple gateways without any additional config. Just set an appropriately named ENV var:
# The standard :default gateway
DATABASE_URL=sqlite://db/app.sqlite
# An :artifacts gateway
DATABASE_URL__ARTIFACTS=sqlite://db/artifacts.sqlite
You can also use ENV vars to set up gateways for slices too:
MY_SLICE__DATABASE_URL=sqlite://db/my_slice.sqlite
MY_SLICE__DATABASE_URL__ARTIFACTS=sqlite://db/my_slice-artifacts.sqlite
For more advanced cases, you can configure gateways explicitly, inside your :db
provider:
Hanami.app.configure_provider :db do
# Explicitly configure a gateway
config.gateway :artifacts do |gw|
# If not configured, will still be filled from `ENV["DATABASE_URL__ARTIFACTS"]`
gw.database_url = "..."
# Specify an adapter to use
gw.adapter :yaml
# Or configure an adapter explicitly
gw.adapter :yaml do |a|
# You can call `a.plugin` here
# Or also `a.extension` if this is an `:sql` adapter
end
end
# Multiple gateways can be configured
config.gateway :another do |gw|
# ...
end
end
All hanami db
commands are multi-gateway-aware. By default, they will operate on all configured databases for an app. You can also target a specific gateway’s database by passing the --app --gateway=gw_name
or --slice=slice_name --gateway=gw_name
arguments.
You can also pass a --gateway
argument to hanami generate migration
to generate a migration for a specific gateway.
For more detail on gateway configuration, see this pull request.
ROM commands and mappers
We also completed the last piece of ROM integration work: integrated commands and mappers. These are advanced components of ROM, and if you need them in a Hanami app, now you can place them in app/db/commands/
and app/db/mappers/
and they’ll be automatically registered.
Full validation contracts for actions
By popular demand, we’ve taken a little detour from our database work to implement support for full dry-validation contracts for your actions. Now you can use contract
within an action class and access all the features of dry-validation, especially rules:
module MyApp
module Actions
module SignUp
class Create < MyApp::Action
contract do
params do
required(:birth_date).filled(:date)
end
rule(:birth_date) do
if value < (Date.today << (12 * 18))
key.failure("you must be 18 years or older")
end
end
end
end
end
end
end
You can also provide a Dry::Validation::Contract
class directly, which is helpful if you want to share validation rules across actions as well as other domain objects:
class Create < MyApp::Action
contract SignUp::Contract
end
Or you can even inject a contract object as a dependency, which is useful if the contract itself has dependencies from elsewhere in your app:
class Create < MyApp::Action
include Deps[contract: "sign_up.contract"]
end
We need your help!
With this beta, we’re another step closer to 2.2.0 proper, so we need your help with testing, especially if you’re a MySQL user, or have a use case that could be served by our multi-gateway support.
We’ve already updated our getting started guides to walk you through your first Hanami 2.2 app, database layer included. Please give this a try, then let us know how you go.
What’s next? A release candidate, then 2.2.0.
Our current goal is to have Hanami 2.2.0 ready by RubyConf, where Sean Collins will be giving an introductory workshop (Day 2, Salon A1).
Between now and then, we plan to make one more release: a single release candidate, towards the end of October. Take a look at our project board to see the work we have remaining.
What’s included?
Today we’re releasing the following gems:
- hanami v2.2.0.beta2
- hanami-assets v2.2.0-beta.2 (npm package)
- hanami-assets v2.2.0.beta2
- hanami-cli v2.2.0.beta2
- hanami-controller v2.2.0.beta2
- hanami-db v2.2.0.beta2
- hanami-reloader v2.2.0.beta2
- hanami-router v2.2.0.beta2
- hanami-rspec v2.2.0.beta2
- hanami-utils v2.2.0.beta2
- hanami-validations v2.2.0.beta2
- hanami-view v2.2.0.beta2
- hanami-webconsole v2.2.0.beta2
For specific changes in this release, please see each gem’s own CHANGELOG.
How can I try it?
> gem install hanami --pre
> hanami new my_app
> cd my_app
> bundle exec hanami dev
Contributors
Thank you to these fine people for contributing to this release!
- Adam Lassek
- Krzysztof Piotrowski
- Kyle Plump — congrats on your first contributions, Kyle!
- Sean Collins
- Tim Riley
Thank you
Thank you as always for supporting Hanami! We can’t wait to hear from you about this beta! 🌸