Hanamiで写真投稿サイトを作ってみた


ファーストサーバ AdventCalendarの16日目です。
普段私は `Ruby on Rails` を使って開発しています。

RubyのフレームワークはRailsだけではありません。
るびまに[こんな記事](http://magazine.rubyist.net/?0056-hanami)が出てました.. **Hanami？？**

RailsとHanamiで写真投稿サイトを作ってみて、比べてみたいと思います！
参考: [Rails Girls](http://railsgirls.jp/)

### 開発環境:computer: 

* Ruby on Rails

```
Ruby 2.3.5
Rails 4.2.5.1
```

* Hanami


```
Ruby 2.3.5
Hanami v1.1.0
```

### Rails:railway_car:で写真投稿サイトを作る:camera: 

簡単な写真投稿サイトを作ります。
[RailsGirls](http://railsgirls.jp/app)を参考にさせていただきました！

* `idea` というmodelを作成、`name` `description` `picture` という項目に登録できる
* `picture` には画像をアップロードできる
といったものです

##### 1.新しいideaを登録

![スクリーンショット 2017-12-14 18.53.31.png](https://qiita-image-store.s3.amazonaws.com/0/85603/b2bb6482-faae-64c8-67cc-3dee0c6863a8.png "スクリーンショット 2017-12-14 18.53.31.png")


##### 2.登録とuploadができる 

![スクリーンショット 2017-12-14 18.55.23.png](https://qiita-image-store.s3.amazonaws.com/0/85603/9dfcf0c1-9bb5-df68-727b-066a9cd2f6f4.png "スクリーンショット 2017-12-14 18.55.23.png")


##### 3. 一覧に表示される

![スクリーンショット 2017-12-14 18.55.51.png](https://qiita-image-store.s3.amazonaws.com/0/85603/f4445a34-8e4b-d717-d3f7-cc4ee93dfc03.png "スクリーンショット 2017-12-14 18.55.51.png")


```rails:console
Idea.last
=> #<Idea id: 1, name: "cherry.rb", description: "cherry.rbです", picture: "スクリーンショット-2014-07-27-14.31.45.png", created_at: "2017-11-28 09:57:34", updated_at: "2017-11-28 09:57:34">
```

これと同様のものをHanamiで作ろうと思います！

### Hanami:cherry_blossom:で写真投稿サイトを作る:camera: 

##### 1.新しいideaを登録

![スクリーンショット 2017-12-14 18.58.21.png](https://qiita-image-store.s3.amazonaws.com/0/85603/c1a24595-2607-f642-360c-e09bc2e2988c.png "スクリーンショット 2017-12-14 18.58.21.png")

##### 2.登録とuploadができる

![スクリーンショット 2017-12-14 18.59.31.png](https://qiita-image-store.s3.amazonaws.com/0/85603/5877bff5-957a-946a-7aba-4d1477513bbd.png "スクリーンショット 2017-12-14 18.59.31.png")

##### 3. 一覧に表示される

![スクリーンショット 2017-12-14 18.59.58.png](https://qiita-image-store.s3.amazonaws.com/0/85603/01a85107-28dd-4dcd-e917-ec6dfba0af87.png "スクリーンショット 2017-12-14 18.59.58.png")

コードは[こちら](https://github.com/tono0123/hanami-image-upload-sample)

RailsとHanamiのここが違ってておもしろかった、と思った点を
あげていきたいとおもいます！

### ここが違うよRailsとHanami

#### 1. RailsはMVC, HanamiはDDD

ここが最大の特徴だと思います。
Hanamiにはmodelというフォルダはなく、lib以下に `Repository` と `Entity` というフォルダがあり、役割がそれぞれ分かれています。
その辺の話は[るびま](http://magazine.rubyist.net/?0056-hanami)に詳しく載っていました。

```hanami
lib/
└── hanami-shrine/
	├── entities/.      -- RDBMSテーブルをRubyで表現する
	└── repositories/.  -- RDBMSテーブルに対するCRUD操作を行う
```

モデルの生成の仕方も以下のようになります。

* Rails: `Idea.new`
* Hanami: `IdeaRepository.new`

#### 2. ControllerとView

Rails:railway_car:はmodelごとにcontrollerが作られます。

```rails
├── controllers
│   ├── application_controller.rb
│   ├── concerns
│   └── ideas_controller.rb
└── views
    ├── ideas
    │   ├── _form.html.erb
    │   ├── _idea.json.jbuilder
    │   ├── edit.html.erb
    │   ├── index.html.erb
    │   ├── index.json.jbuilder
    │   ├── new.html.erb
    │   ├── show.html.erb
    │   └── show.json.jbuilder
    └── layouts
        └── application.html.erb
```

Hanami:cherry_blossom:は機能ごとにcontrollerが作られます。
controllerやviewのテストが小さく書けそうです！

```hanami
├── controllers
│   └── ideas
│       ├── create.rb
│       ├── destroy.rb
│       ├── index.rb
│       ├── new.rb
│       └── show.rb
└── views
    ├── application_layout.rb
    └── ideas
        ├── create.rb
        ├── index.rb
        ├── new.rb
        └── show.rb
```

#### 3. 使用するGem

ファイルアップロード機能を実装するのに、以下のgemを使いました。

Rails:railway_car:

```
gem 'carrierwave'
```

Hanami:cherry_blossom:

```
gem 'shrine'
gem 'hanami-shrine', '0.2.1'
```

実装するにあたり、このへんを参考にさせていただきました
https://github.com/janko-m/shrine
http://katafrakt.me/2016/02/04/shrine-hanami-uploads/


### まとめ

Rails:railway_car:は`便利なgemやmethodが多い & ドキュメントも多い`ので、やはり使いやすいです。
ですが、やはり構造上、`機能が増えていくとFat Modelになってしまう懸念`があります。

Hanami:cherry_blossom:はまだまだ発展途上でできないことも多いですが、機能追加ごとにファイルが分かれる & テストも分かれるので、`メンテナンスしやすい`のではないかなと思いました。

今度はちゃんとテストも書こう.. :pencil2: