アプリのサーバーサイドをRailsで構築する

# 概要
- 自分のiOSアプリのサーバーサイドが欲しいと思い、Railsでサーバーサイドを構築しようと思う
- 一度やったけど、とにかくやることが多いので忘れないように残しておく

# やりたいこと
- 無料でやりたい
- 本番環境とステージング環境の2つが欲しい
- DBはMySQLを使いたい
- ステージング環境にpushするとき、テストとコード解析を走らせて結果を slack に通知したい

## 無料でやりたい
- GitHubでプライベートリポは有料だが、Bitbucketは無料
- Herokuの無料枠は、[2016年6月1日に変更](https://blog.heroku.com/announcing_heroku_free_ssl_beta_and_flexible_dyno_hours#flexible-free-dyno-hours)があり、以下の内容になる
 - クレジットカードを登録すると `1000 dyno hours / 月`になり、未登録だと `550 dyno hours / 月`
 - 無料枠の80%を越えるとメールで通知、100%で再び通知して無料枠は来月まで停止、来月になると再び無料枠がもらえる
 - 無料枠はアプリごとではなく、アカウントごとに割り当てるので、Herokuで利用中のアプリで無料枠を取り合う
 - 30分アクセスが一度もなかったら、Herokuのアプリはスリープ状態になる
 - **要するに、24時間フル稼働（24時間 × 31日 = 744時間）のアプリ一つと、そのアプリ用のステージング環境で色々試す時間が（1000 - 744 = 256時間）あるので、充分無料枠でやりくりできそう**
- werckerは、Bitbucket のプライベートリポでも無料でつかえて、ジョブは2個まで無料

## Heroku のセットアップ
- Railsチュートリアルの説明が一番わかりやすい
- [Railsチュートリアルは数日前に第4版がリリース](http://railstutorial.jp/chapters/beginning?version=5.0#sec-heroku_setup)されて、Rails5対応になったのでセットアップはそちらを参照

## DBはMySQLを使いたい
- Heroku のデフォルトでは PostgreSQL なので自分で変えないといけない
- 公式の内容を見つつ、下記の記事をやれば問題なく MySQL に変更できた
 - [Configuring your Ruby application to use ClearDB](https://devcenter.heroku.com/articles/cleardb#configuring-your-ruby-application-to-use-cleardb) 
 - [HerokuでMySQLを使うときはDATABASE_URLを書き換える](http://qiita.com/SomeyaNaoki/items/1167fa816fa9647e4464)  
- なお、Heroku の本番環境のMySQLのDBを確認するには、下記の方法で出来る

> $ heroku config | grep CLEARDB_DATABASE_URL
> CLEARDB_DATABASE_URL: mysql2://(username):(password)@(host)/(database)?reconnect=true 
>
> $ mysql -u (username) -p -h (host) (database)
> Enter password: (password)
>
> 参照：http://xyk.hatenablog.com/entry/2014/09/29/184727

## 本番環境とステージング環境の2つが欲しい
- 下記の**コマンドだけ**で既存のHerokuアプリをフォークしてくれる
 - remoteの名前は頭に `stg-` とかつけると、tabボタンで補完したときに間違えなくていい
 - 公式に書いてあるが、フォーク先を作成する必要はない

> Don’t create targetapp yourself. heroku fork creates the target app as part of the forking process.
>
> 参照：https://devcenter.heroku.com/articles/fork-app

```
$ heroku fork -a アプリケーションの名前 stg-アプリケーションの名前
```

- ちゃんと出来てるかを確認して、ステージングにpushしてみる

```
$ git remote -v
origin
heroku
stg-アプリケーションの名前
$ git push stg-アプリケーションの名前 master
```

- **注意するのは、例えばステージング環境に開発ブランチをpushしたい場合は、下記のようにする**

> 開発ブランチ名が'dev'の場合
> $ git push stg-heroku dev:master
>
> 参照：http://qiita.com/etet-etet/items/b9c1420f3879193edaec


## 本番環境をスリープさせない
- 下記の記事がわりやすく、すぐにできます
 - [【2016年版】NewRelicを使って無料でHerokuのSleepを防ぐ](http://qiita.com/tomomichi/items/07c5ad7d8f69f8e45a90)


## ステージング環境にpushするとき、テストとコード解析を走らせて結果を slack に通知したい
- RSpec と rubocop を使う。セットアップは割愛
 - rubocopのデフォルトだと、1メソッドは10行以内で書くように指摘されるが、初心者には辛いのでオフにした

```.rubocop.yml
<省略>

# 1メソッドの行数をチェック。デフォルトは10行でコメントは対象外。
Metrics/MethodLength:
  Enabled: false
  # CountComments: false
  # Max: 10

<省略>
```
 
- wercker でアカウント作成して Bitbucket の rails の repository を選択する
- wercker の管理画面で environment タブを選択して、 $SLACK_URL を作成する

wercker の管理画面で environment タブを選択 | 
--- | 
<img src="https://qiita-image-store.s3.amazonaws.com/0/37385/526cb835-2f0f-d6e5-8b57-02e7ca14dac8.png" width="900"/> |
- `.gitignore` とか `Gemfile` がある場所に、 `wercker.yml`を作成して `git push` するだけ
- MySQLの設定は下記の記事が役立つ
 - [WerckerでRailsのCIを回す](http://qiita.com/hidechae/items/bc02192c06f0c4e39ef6)
 - [Bitbucket + Werckerを使ってプライベートリポジトリで無料CI（PHPUnit, MySQL)](http://qiita.com/yuichiroTCY/items/f2fc8df922f80bcb8ad3)

```wercker.yml
box: ruby

services:
  - id: mysql
    env:
      MYSQL_ROOT_PASSWORD: rootpasswd
      MYSQL_USER: testuser
      MYSQL_PASSWORD: testpasswd
      MYSQL_DATABASE: testdb
build:
    steps:
        - script:
          name: delete docker images cache
          code: |
            rm -rf $WERCKER_CACHE_DIR
        - bundle-install
        - rails-database-yml
        - script:
            name: Echo Ruby Information
            code: |
               echo “ruby version $(ruby –version) running!”
               echo “from location $(which ruby)”
               echo -p “gem list: $(gem list)”
        - script:
            name: Run Rubocop
            code: bundle exec rubocop
        - script:
            name: Set Up DB
            code: RAILS_ENV=test bundle exec rake db:schema:load
        - script:
            name: Run RSpec
            code: bundle exec rspec
    after-steps:
        - wantedly/pretty-slack-notify@0.2.14:
            webhook_url: $SLACK_URL
```

- 今回は slack の通知を [wantedly製のものでやってみました](https://github.com/wantedly/step-pretty-slack-notify) 

上がデフォルトの通知、下はwantedly製で通知 | 
--- | 
<img src="https://qiita-image-store.s3.amazonaws.com/0/37385/971b3db1-c629-c20e-4c75-1624adb580e9.png" width="900"/> |


## JSONで返す
- Rails5のAPIモードで、`respond_to`メソッドを使用するときは、`ActionController::API`に`include ActionController::MimeResponds`が必要
 - [Undefined instance method “respond_to” in Rails 5 API Controller](http://stackoverflow.com/questions/35983628/undefined-instance-method-respond-to-in-rails-5-api-controller)

```application_controller.rb
class ApplicationController < ActionController::API
  include ActionController::MimeResponds

  def respond(response_body)
    respond_to do |format|
      response.headers['Content-Type'] = 'application/json; charset=utf-8'
      format.any { render json: response_body }
    end
  end
end
```

```example_controller.rb
class ExampleController < ApplicationController
  # (GET) /v1/example
  def index
    respond({key:'hoge'})
  end
end
```

# おわりに
- 先人の知恵が本当に役立った
- iOSばかりだった私には、サーバーサイドの環境構築はなかなかヘビーだった
- 公開後に気づいたけどiOSは関係なかった、単純にサーバーサイドの環境構築だこれ

# 参考資料
- [Ruby on Rails チュートリアル-Herokuのセットアップ](http://railstutorial.jp/chapters/beginning?version=5.0#sec-heroku_setup)
- [Githubのプライベートリポジトリでも無料で使えるCI、Werckerを使ってrails newからHerokuのデプロイまでやってみる](http://blog.mah-lab.com/2014/01/08/rails-wercker-heroku-deploy/)
- [Flexible Free Dyno Hours](https://blog.heroku.com/announcing_heroku_free_ssl_beta_and_flexible_dyno_hours#flexible-free-dyno-hours) 
- [wantedly/step-pretty-slack-notify](https://github.com/wantedly/step-pretty-slack-notify)
- [【2016年版】NewRelicを使って無料でHerokuのSleepを防ぐ](http://qiita.com/tomomichi/items/07c5ad7d8f69f8e45a90)
- [Undefined instance method “respond_to” in Rails 5 API Controller](http://stackoverflow.com/questions/35983628/undefined-instance-method-respond-to-in-rails-5-api-controller)
- [HerokuでMySqlの設定をする](http://qiita.com/fukumone/items/b8934f78f841b19edbbe) 
- [HerokuでMySQLを使うときはDATABASE_URLを書き換える](http://qiita.com/SomeyaNaoki/items/1167fa816fa9647e4464)
- [WerckerでRailsのCIを回す](http://qiita.com/hidechae/items/bc02192c06f0c4e39ef6)
- [Bitbucket + Werckerを使ってプライベートリポジトリで無料CI（PHPUnit, MySQL)](http://qiita.com/yuichiroTCY/items/f2fc8df922f80bcb8ad3)
- [Heroku で Rails4 + MySQL を動かす](http://xyk.hatenablog.com/entry/2014/09/29/184727)