Skip to content
Permalink
Browse files

Merge pull request #275 from hanami/announcing-v100beta1

Announcing v1.0.0.beta1
  • Loading branch information...
jodosha committed Feb 14, 2017
2 parents fb557bc + 5aa2132 commit 49e2d673e50eaa28f6e52df9173d425c5f491f3f
@@ -212,7 +212,7 @@ def encode_text(text)
end

def hanami_version
'0.9.2'
'1.0.0.beta1'
end
end

@@ -115,3 +115,5 @@ categories:
title: v0.8.0
- path: v090
title: v0.9.0
- path: v100beta1
title: v1.0.0.beta1
@@ -0,0 +1,162 @@
---
title: Announcing Hanami v1.0.0.beta1
date: 2017-02-14 13:33 UTC
tags: announcements
author: Oana Sipos
image: true
excerpt: >
Feature freeze, project logger, automatic logging of requests, SQL queries, and migrations. Minor bug fixes.
---

This `v1.0.0.beta1` release introduces Hanami [feature freeze](https://en.wikipedia.org/wiki/Freeze_(software_engineering)) for 1.0, alongside with a couple of features, and a few bug fixes.

Since now on, **Hanami API's are stable and won't be changed until 2.0**.

The stable release (`v1.0.0`) will happen between the end of March and the beginning of April 2017, which coincides with the [Hanami season in Japan](http://www.japan-guide.com/sakura/). 🌸

In the meantime we'll release other _beta_ and _release candidate_ versions.

## Features

Hanami is now compatible with Ruby 2.3+ (including the latest 2.4) and with Rack 2.0 only.

### Project Logger

We introduced the project logger, available at `Hanami.logger`.
If you need to log an information, use it like this: `Hanami.logger.debug "hello"`.

Because of this change, the application loggers were removed (eg. `Web.logger`, `Admin.logger`).
The logger settings for each single application are not supported anymore (eg. `apps/web/application.rb`).
In order to configure the logger, please edit `config/environment.rb`.

### Automatic Logging

A project that uses Hanami will automatically log each incoming HTTP request, SQL queries and migrations output.

When a project is used in development mode, the logging format is human readable:

```ruby
[bookshelf] [INFO] [2017-02-11 15:42:48 +0100] HTTP/1.1 GET 200 127.0.0.1 /books/1 451 0.018576
[bookshelf] [INFO] [2017-02-11 15:42:48 +0100] (0.000381s) SELECT "id", "title", "created_at", "updated_at" FROM "books" WHERE ("book"."id" = '1') ORDER BY "books"."id"
```

For production environment, the default format is JSON.
JSON is parseable and more machine oriented. It works great with log aggregators or SaaS logging products.

```json
{"app":"bookshelf","severity":"INFO","time":"2017-02-10T22:31:51Z","http":"HTTP/1.1","verb":"GET","status":"200","ip":"127.0.0.1","path":"/books/1","query":"","length":"451","elapsed":0.000391478}
```

Migrations will print on standard output the operations applied to the database schema.

```shell
➜ bundle exec hanami db migrate
[hanami] [INFO] Begin applying migration 20170213123250_create_books.rb, direction: up
[hanami] [INFO] (0.001756s) CREATE TABLE `books` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT, `name` varchar(255) NOT NULL, `created_at` timestamp NOT NULL, `updated_at` timestamp NOT NULL)
[hanami] [INFO] (0.001738s) INSERT INTO `schema_migrations` (`filename`) VALUES ('20170213123250_create_books.rb')
[hanami] [INFO] Finished applying migration 20170213123250_create_books.rb, direction: up, took 0.004091 seconds
```

### Improved Model Generator

The model generator now creates a migration file for a given entity.

```shell
➜ bundle exec hanami generate model book
create lib/bookshelf/entities/book.rb
create lib/bookshelf/repositories/book_repository.rb
create db/migrations/20170213123250_create_books.rb
create spec/bookshelf/entities/book_spec.rb
create spec/bookshelf/repositories/book_repository_spec.rb
```

It generates an entity with the corresponding repository, migration, and testing code.

The migration will already contain the code for the creation of the table, the primary key and the timestamps:

```ruby
# db/migrations/20170213123250_create_books.rb
Hanami::Model.migration do
change do
create_table :books do
primary_key :id
column :created_at, DateTime, null: false
column :updated_at, DateTime, null: false
end
end
end
```

### `config/boot.rb`

New projects will be generated with a new file: `config/boot.rb`

```ruby
require_relative './environment'
Hanami.boot
```

This is useful to boot a Hanami project **outside of** the server or the console.
A typical use case is [Sidekiq](http://sidekiq.org). If you want to run background jobs with this queue, you can start the process with:

```shell
bundle exec sidekiq -r ./config/boot.rb
```

### Minor Changes

For the entire list of changes, please have a look at our [CHANGELOG](https://github.com/hanami/hanami/blob/master/CHANGELOG.md) and [features list](https://github.com/hanami/hanami/blob/master/FEATURES.md).

## Released Gems

* `hanami-1.0.0.beta1`
* `hanami-model-1.0.0.beta1`
* `hamami-controller-1.0.0.beta1`
* `hanami-assets-1.0.0.beta1`
* `hanami-mailer-1.0.0.beta1`
* `hanami-helpers-1.0.0.beta1`
* `hanami-view-1.0.0.beta1`
* `hanami-validations-1.0.0.beta1`
* `hanami-router-1.0.0.beta1`
* `hanami-utils-1.0.0.beta1`

## Contributors

We're grateful for each person who contributed to this release. These lovely people are:

* [Adrian Madrid](https://github.com/aemadrid)
* [Alfonso Uceda](https://github.com/AlfonsoUceda)
* [Andy Holland](https://github.com/AMHOL)
* [Bhanu Prakash](https://github.com/bhanuone)
* [Gabriel Gizotti](https://github.com/gizotti)
* [Jakub Pavlík](https://github.com/igneus)
* [Kai Kuchenbecker](https://github.com/kaikuchn)
* [Ksenia Zalesnaya](https://github.com/ksenia-zalesnaya)
* [Leonardo Saraiva](https://github.com/vyper)
* [Lucas Hosseini](https://github.com/beauby)
* [Marcello Rocha](https://github.com/mereghost)
* [Marion Duprey](https://github.com/TiteiKo)
* [Marion Schleifer](https://github.com/marionschleifer)
* [Matias H. Leidemer](https://github.com/matiasleidemer)
* [Mikhail Grachev](https://github.com/mgrachev)
* [Nick Rowlands](https://github.com/rowlando)
* [Nikita Shilnikov](https://github.com/flash-gordon)
* [Oana Sipos](https://github.com/oana-sipos)
* [Ozawa Sakuro](https://github.com/sakuro)
* [Pascal Betz](https://github.com/pascalbetz)
* [Philip Arndt](https://github.com/parndt)
* [Piotr Solnica](https://github.com/solnic)
* [Semyon Pupkov](https://github.com/artofhuman)
* [Thorbjørn Hermansen](https://github.com/thhermansen)
* [Tiago Farias](https://github.com/tiagofsilva)
* [Victor Franco](https://github.com/docStonehenge)
* [Vladimir Dralo](https://github.com/vladra)
* [alexd16](https://github.com/alexd16)
* [b264](https://github.com/b264)
* [yjukaku](https://github.com/yjukaku)

## How To Update Your Project

If you're upgrading you project from `v0.9`, please have a look at the related [upgrade guide article](/guides/upgrade-notes/v100beta1).
Binary file not shown.
@@ -85,11 +85,28 @@ Generate an entity and a repository with a single command
% bundle exec hanami generate model book
create lib/bookshelf/entities/book.rb
create lib/bookshelf/repositories/book_repository.rb
create db/migrations/20170213123250_create_books.rb
create spec/bookshelf/entities/book_spec.rb
create spec/bookshelf/repositories/book_repository_spec.rb
```

It generates an entity with the corresponding repository and test code.
It generates an entity with the corresponding repository, migration, and testing code.

The migration will already contain the code for the creation of the table, the primary key and the timestamps:

```ruby
# db/migrations/20170213123250_create_books.rb
Hanami::Model.migration do
change do
create_table :books do
primary_key :id
column :created_at, DateTime, null: false
column :updated_at, DateTime, null: false
end
end
end
```

### Migrations

@@ -64,7 +64,7 @@ To create a new Hanami project, we need to install the Hanami gem from Rubygems.
Then we can use the new `hanami` executable to generate a new project:

```
% gem install hanami
% gem install hanami --pre
% hanami new bookshelf
```

@@ -339,22 +339,45 @@ A **layout** is like any other template, but it is used to wrap your regular tem
The `yield` line is replaced with the contents of our regular template.
It's the perfect place to put our repeating headers and footers.

### Migrations To Change Our Database Schema
## Modeling Our Data With Entities

Hard-coding books in our templates is, admittedly, kind of cheating.
Let's add some dynamic data to our application.

As first thing, we need a table in our database to hold our book data.
We can use a **migration** to make the required changes.
Use the migration generator to create an empty migration:
We'll store books in our database and display them on our page.
To do so, we need a way to read and write to our database.
Enter entities and repositories:

* an **entity** is a domain object (eg. `Book`) uniquely identified by its identity.
* a **repository** mediates between entities and the persistence layer.

Entities are totally unaware of database.
This makes them **lightweight** and **easy to test**.

For this reason we need a repository to persist the data that a `Book` depends on.
Read more about entities and repositories in the [models guide](/guides/models/overview).

Hanami ships with a generator for models, so let's use it to create a `Book` entity and the corresponding repository:

```
% bundle exec hanami generate migration create_books
% bundle exec hanami generate model book
create lib/bookshelf/entities/book.rb
create lib/bookshelf/repositories/book_repository.rb
create db/migrations/20161115110038_create_books.rb
create spec/bookshelf/entities/book_spec.rb
create spec/bookshelf/repositories/book_repository_spec.rb
```

This gives us a file name like `db/migrations/20161115110038_create_books.rb` that we can edit:
The generator gives us an entity, a repository, a migration, and accompanying test files.

### Migrations To Change Our Database Schema

As first thing, we need to shape our database table, by editing the migration:


```ruby
# db/migrations/20161115110038_create_books.rb
Hanami::Model.migration do
change do
create_table :books do
@@ -380,33 +403,6 @@ Let's prepare our database:
% bundle exec hanami db prepare
```

## Modeling Our Data With Entities

We'll store books in our database and display them on our page.
To do so, we need a way to read and write to our database.
Enter entities and repositories:

* an **entity** is a domain object (eg. `Book`) uniquely identified by its identity.
* a **repository** mediates between entities and the persistence layer.

Entities are totally unaware of database.
This makes them **lightweight** and **easy to test**.

For this reason we need a repository to persist the data that a `Book` depends on.
Read more about entities and repositories in the [models guide](/guides/models/overview).

Hanami ships with a generator for models, so let's use it to create a `Book` entity and the corresponding repository:

```
% bundle exec hanami generate model book
create lib/bookshelf/entities/book.rb
create lib/bookshelf/repositories/book_repository.rb
create spec/bookshelf/entities/book_spec.rb
create spec/bookshelf/repositories/book_repository_spec.rb
```

The generator gives us an entity, repository and accompanying test files.

### Working With Entities

An entity is something really close to a plain Ruby object.
@@ -59,23 +59,28 @@ It defaults to SMTP (`:smtp`) for production environment, while `:test` is autom
The second optional argument is a set of arbitrary configurations that we want to pass to the configuration:

```ruby
# lib/bookshelf.rb
# config/environment.rb
# ...
Hanami::Mailer.configure do
Hanami.configure do
# ...
delivery do
development :test
test :test
production :smtp,
address: "smtp.gmail.com",
port: 587,
domain: "bookshelf.org",
user_name: ENV['SMTP_USERNAME'],
password: ENV['SMTP_PASSWORD'],
authentication: "plain",
enable_starttls_auto: true
mailer do
root Hanami.root.join("lib", "kaba", "mailers")
# See http://hanamirb.org/guides/mailers/delivery
delivery :test
end
end.load!
# ...
environment :production do
# ...
mailer do
delivery :smtp, address: ENV['SMTP_HOST'], port: ENV['SMTP_PORT']
end
end
end
```

For advanced configurations, please have a look at `mail` [gem](https://github.com/mikel/mail) by Mikel Lindsaar.
@@ -91,16 +96,21 @@ If we need to a custom delivery workflow, we can pass a class to the configurati
Here's an example on how to use [Mandrill API](https://mandrillapp.com/api/docs/) to deliver emails.

```ruby
# lib/bookshelf.rb
# config/environment.rb
# ...
require 'lib/mailers/mandrill_delivery_method'
Hanami::Mailer.configure do
Hanami.configure do
# ...
delivery do
production MandrillDeliveryMethod, api_key: ENV['MANDRILL_API_KEY']
environment :production do
# ...
mailer do
production MandrillDeliveryMethod, api_key: ENV['MANDRILL_API_KEY']
end
end
end.load!
end
```

The object MUST respond to `#initialize(options = {})` and to `#deliver!(mail)`, where `mail` is an instance of [`Mail::Message`](https://github.com/mikel/mail/blob/master/lib/mail/mail.rb).

0 comments on commit 49e2d67

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