CodeIgniter から参照されるデータベースを残しつつ、新たに Rails で Web API を開発した話

# 既存環境
PHP5.4 / CodeIgniter 

# やりたいこと
+ ネイティブアプリ向けに Web API を追加開発したい。
+ Ruby / Rails で書きたい。
+ テストもしっかり書きたい。既存ソースにはない。
+ 既存のデータベース(MySQL)は、そのまま使いまわしたい。

# 問題点
1. Rails で Web API を作成する際の情報が少ない
1. Rails デフォルトの Database が SQLite
1. 既存の Database を利用した情報が意外と少ない
1. 既存のテーブル名が Rails の規約に沿っていない

# 解決策
## 1. Rails で Web API を作成する際の情報が少ない
Rails で Web API を作成する際は [rails-api](https://github.com/rails-api/rails-api) が使いやすかった。この gem を利用するにあたり、下記の参考になった。

参照：[#348 The Rails API Gem - RailsCasts](http://railscasts.com/episodes/348-the-rails-api-gem?view=asciicast) 

テストの書き方は下記が参考になった。

参照：[Rails でつくる API のテストの書き方（RSpec + FactoryGirl） - 彼女からは、おいちゃんと呼ばれています](http://blog.inouetakuya.info/entry/2013/10/27/200111)

## 2. Rails デフォルトの Database が SQLite

今回は、RSpec を導入したいのと、 MySQL を利用したいため、下記の通りプロジェクトを作成した。

```bash
$ bundle exec rails-api new api --skip-bundle -T -d mysql
```

## 3. 既存のDatabaseを利用した情報が意外と少ない
database.yml を既存のデータベースに向け以下のコマンドを実行することで、 schema.rb を生成できた。

```bash
$ bundle exec rake db:schema:dump
```

全く同じ疑問を持っていた方がいた。

参照：[mysql - Putting Rails over top of an existing database - Stack Overflow](https://stackoverflow.com/a/4692958/1285818)

### テスト用のデータベースを作成する
テストを実行すると、以下のようなメッセージがでた。

```
ActiveRecord::NoDatabaseError: Unknown database 'test'Run \`$ bin/rake db:create db:migrate\` to create your database
```

既存のデータベースを利用しているとはいえ、これまでテストがなかったのでテスト用のDBを用意してあげる必要がある。

```bash
$ bundle exec rake db:create
```

## テスト用のテーブルを作成する
データベースの作成後、再度テストを実行するとまた怒られた。

```
ActiveRecord::StatementInvalid:
Mysql2::Error: Table 'test.foobar' doesn't exist: SHOW FULL FIELDS FROM \`foobar\`
```

今度は、テスト用にテーブルを作成してあげる必要がある。

```bash
$ bundle exec rake db:schema:load RAILS_ENV=test
```
--> 今のところこれが正解。「今のところ」と行っているのは、コロコロ仕様が変わっているから。

```bash
$ bundle exec rake test:prepare
rake aborted!
Don't know how to build task 'test:prepare'
```
--> これができたのは Rails 4.0 系だけ。4.1 で deprecate された。
参照：[Ruby on Rails 4.1 Release Notes — Ruby on Rails Guides](http://edgeguides.rubyonrails.org/4_1_release_notes.html#active-record-deprecations)

```bash
$ bundle exec rake db:test:prepare
WARNING: db:test:prepare is deprecated. The Rails test helper now maintains your test schema automatically, see the release notes for details.
```
--> Rails 3 系では使えたが 4.1 で deprecate された。とりあえず動くけど WARN がでる。
参照：[Ruby on Rails 4.1 Release Notes — Ruby on Rails Guides](http://edgeguides.rubyonrails.org/4_1_release_notes.html#active-record-deprecations)


# 4. 既存のテーブル名が Rails の規約に沿っていない
`self.table_name`で解決できる。

まずは、migrationを作成したくないので`--migration=false`オプションをつけてモデルを生成する。

```bash
$ bundle exec rails g model user --migration=false
```

そして、モデルクラスに既存のテーブル名を指定する。

```ruby
class User < ActiveRecord::Base
	self.table_name = 'user'
end
```

# 余談
## spec ファイルの動的生成
本来は RSpec のインストール (`rails g rspec:install`) を実行してから `rails generator [scaffold|controller|model]` で各ファイルを生成すべきとろを忘れてしまっていたので、 spec ファイルが生成されていなかった。そんな時は、 `rails g integration_test task` で spec ファイルを生成することができた。

## rspec の実行
### 全てのテストを実行
```
$ bundle exec rake spec:requests
```

### 特定のスペックだけ実行
```
$ bundle exec rspec spec/requests/users_spec.rb 
```

### 特定のテストケースだけ実行
```
$ bundle exec rspec spec/requests/users_spec.rb:50
```