Railsアプリを作る時のテンプレ(個人的なテンプレ)

最近サービスのプロトタイプを作る時は大抵RailsとAngularJSを使っているが、
時間が空くと手順がわからなくなるので、備忘録として残しておく。

2015.08時点 Rails 4.2.3を使った場合のテンプレ

# 前提
* Ruby on Rails 3以降を使ったプロジェクトをサーバー上で動かしたことがある
* Herokuを使ったことがある

# Railsプロジェクトを作成
Railsを最新版にする

```
gem install rails
rails -v
```

新しいRailsアプリの作成

```
rails new myapp
```

※2014.12追記: Ruby 2.1 + Rails 4.1.8で実行したところ`bundle install`中に`sass 3.2.19`のインストールでエラーが起きた。`gem install spring`で`spring`を手動インストールしてから実行したところ解決。

# Haml, Bootstrapを入れる
`Gemfile`にgemを追加

```
gem "haml-rails"
gem "therubyracer"
gem "less-rails", "~> 2.7.0"
gem "twitter-bootstrap-rails"
```

※2015.08追記: Rails 4.2.3で実行したところ`stylesheet_link_tag`の中のlessの処理の部分で`undefined method ```[]' for nil:NilClass`エラーが起きた。`less-rails`のgithubページの内容に従い、バージョン指定`"~> 2.7.0"`をしたところ解決した。

gemのインストールとbootstrapの適用

```
# 必要なgemをインストール
bundle
# Bootstrapをプロジェクトにインストール
rails g bootstrap:install less
# layoutに適用
rails g bootstrap:layout application
# application.html.erbを削除(.hamlの方を使うため)
rm app/views/layouts/application.html.erb
```

# アセットのログを消す

```
gem 'quiet_assets', group: :development
```

```
bundle
```

# Scaffoldで動作確認
Scaffoldを作って動かしてみる

```
rails g scaffold Book title:string author:string
bundle exec rake db:migrate
```

サーバーを起動して動作確認

```
rails s
```

ここらへんまで動いたらgitレポジトリつくるなりする。

# AngularJSを入れる
`application.html.haml`のtitleタグの下あたりで、AngularJSを読み込む。CDNからロードするのが手軽。

```
%script(src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js")
```

`books/index.html.haml`の下部あたりで、AngularJSを使えることを確認してみる。

```
#ngExp(ng-app="")
  %input(type="text" ng-model="data.message")
  %p
    Hello {{data.message}}
```

`books/index.html.haml`で、HTMLと同じBookのリストをAngularJSで表示してみる。

```books/index.html.haml
%h1 Listing books

%table
  %tr
    %th Title
    %th Author
    %th
    %th
    %th

  - @books.each do |book|
    %tr
      %td= book.title
      %td= book.author
      %td= link_to 'Show', book
      %td= link_to 'Edit', edit_book_path(book)
      %td= link_to 'Destroy', book, :method => :delete, :data => { :confirm => 'Are you sure?' }

%br

= link_to 'New Book', new_book_path

#ngExp(ng-controller="BooksCtrl")
  %ul
    %li(ng-repeat="book in books")
      {{book.title}} / {{book.author}}
```

```books.js.coffee
angular.module('myapp', [])
  .controller "BooksCtrl", ["$scope", "$http", ($scope, $http) ->
    $http.get('/books.json').success (data) ->
      $scope.books = data
    ]
```

```application.html.haml
!!! 5
%html(lang="en" ng-app="myapp") <- ng-appを追加
```
### ng-resource
ng-resourceもCDN経由で読み込める。

```
%script(src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-resource.min.js")
```

```
angular.module('myapp', ["ngResource"])
  .factory 'Book', ["$resource", ($resource) ->
    $resource('/books/:id.json', {id: '@id'}, {update: { method: 'PUT' }})
    ]
  .controller "BooksCtrl", ["$scope", "Book", ($scope, Book) ->
    $scope.books = Book.query()
```

#### CSRF対策
http://alexpotrykus.com/blog/2013/12/07/angularjs-with-rails-4-part-1/

#### Turbolinks対策
http://kurtfunai.com/2014/08/angularjs-and-turbolinks.html

# HerokuにDeployする
## HerokuではPostgreSQLを使う
`Gemfile`は、production(Heroku)の時に`pg`を使うように設定。`rails_12factor`はheroku上でrailsアプリを動かす際に必要なgem。

```
group :development do
  gem 'sqlite3'
end
group :production do
  gem 'pg'
  gem 'rails_12factor'
end
```

`bundle`コマンドでgemを更新する。その後、`database.yml`の`production`ブロックの内容をpostgresを使う設定に書き換える。

```database.yml
production:
  adapter: postgresql
  encoding: unicode
  database:
  pool: 5
  username:
  password:
```

## Gitレポジトリ作る(まだ作ってなかったら)
```
git init
git add .
git commit -m "Initial commit."
```

## heroku上にアプリをつくる
```
heroku create
```

`heroku create`コマンドでExconのエラーが出た場合は`heroku update`で直るかも
http://stackoverflow.com/questions/17268517/heroku-client-internal-error-unable-to-verify-certificate

## herokuにpush
```
git push heroku master
```

## DBのマイグレーション
```
heroku run rake db:migrate
```

## Minification / Uglification対策
`production`モードでjsのminification / uglificationを行っているとDIがうまく行かなくなる場合があるので、問題が起きないスタイルでjsを書いてく必要がある。

```
angular.module('myapp', [])
  .controller "BooksCtrl", ["$scope", "$http", ($scope, $http) ->
    $http.get('/books.json').success (data) ->
      $scope.books = data
    ]

```

## その他
忘れないうちにherokuのアプリ名は変更しておく。じゃないと後で探すのが面倒になる。

```
heroku apps:rename sample_project
```

### ドメインの追加

```
heroku domains:add www.example.com
```

あとは、ドメインの設定側で

```
cname www sample_project.herokuapp.com.
```

----

参考

* https://devcenter.heroku.com/articles/getting-started-with-rails4#use-postgres
* http://morizyun.github.io/blog/beginner-rails-heroku-tutorial/
* http://stackoverflow.com/questions/10659890/angularjs-rails-problems-when-compressing-assets
* http://alexpotrykus.com/blog/2013/12/07/angularjs-with-rails-4-part-1/