Rails4 で Knockout ＆ Bootstrap ＆ Coffee ＆ SASS ＆ Haml な環境を構築する


フロントエンドのちょっとした動きを **Knockout.js** と **CoffeeScirpt** で書きつつ、デザインは **Twitter Bootstrap** と **Font Awersome** (アイコン) で最低限のものを確保し、マークアップは **Haml** (HTMLの代替) と **SASS** (CSSの代替) で記述する、という構成です。

**Knockout.js** を利用する理由は **View で薄く使う** に適していそうだからです。

個人的に何度も繰り返して作りそうな環境なので、手順をここに残します。
（ちなみに CoffeeScript と SASS は Rails4 で標準なので、特に何もしていない。）

また、この手順で作った Seed は GitHub にも置きました。よければご利用ください。
⇒ https://github.com/hkusu/Knockout.js_Rails_seed

### 前提

- OS のバージョン： `Mac OS X 10.9.5 (Mavericks)`
- Ruby のバージョン： `2.1.2`
- Rails のバージョン： `4.1.1`

# 環境構築の手順

## ① Railsのプロジェクト作成

```shell:
$ bundle exec rails new hoge_app --skip-bundle -T
```

> - テストは Rspec を使いたいので `-T` を指定。
> - データベースはデフォルトの sqlite3 を採用。

## ② Gemfileの編集

```ruby:rails_angular_app/Gemfile
#gem 'turbolinks'

gem 'knockoutjs-rails'
gem 'bootstrap-sass'
gem 'font-awesome-sass'
gem 'haml-rails'
gem 'erb2haml', group: :development

gem 'better_errors', group: [:development, :test]
gem 'binding_of_caller', group: [:development, :test]
gem 'brakeman', group: :development
gem 'rails_best_practices', group: :development
gem 'pry-rails', group: [:development, :test]
gem 'rspec', group: [:development, :test]
gem 'rspec-rails', group: [:development, :test]
gem 'factory_girl_rails', group: [:development, :test]
gem 'rubocop', group: :development
gem 'rubocop-checkstyle_formatter', group: :development
```

> - turbolinks は Knockout.js と相性が悪いので外しておく。
> - ついでに使いそうな gem 郡も追加。
> - gemのバージョンは固定した方がよいかも。

## ③ Bundler で gem をインストール

```shell:
$ cd hoge_app
$ bundle install --path vendor/bundle
```

- インストールが終わったら一旦、ここで動作確認。ブラウザで `http://127.0.0.1:3000` にアクセスし、お馴染みの画面が表示されればOK。

	```shell:
	$ cd hoge_app
	$ ./bin/rails s
	```

## ④ Spring の有効化

```shell:
$ cd hoge_app
$ bundle exec spring binstub --all
```

## ⑤ Haml 関連

既存の `.erb` ファイルを `.haml` ファイルへ変換。

```shell:
$ cd hoge_app
$ ./bin/rake haml:replace_erbs
```

## ⑥ Knockout.js 関連

- `app/assets/javascripts/application.js` の修正。

	```javascript:app/assets/javascripts/application.js
	//= require knockout ←この行を追記
	//= require turbolinks ←この行を削除
	```

- ``app/views/layouts/application.html.haml` の修正。

	```diff:app/views/layouts/application.html.haml
    - = stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true
    - = javascript_include_tag 'application', 'data-turbolinks-track' => true
    + = stylesheet_link_tag    'application', media: 'all'
    + = javascript_include_tag 'application'
	```

	> turbolinks を無効化している。

## ⑦ Twitter Bootstrap & Font Awesome 関連

- `app/assets/stylesheets/application.css.scss` を新規に作成して編集。

	```shell:
	$ touch app/assets/stylesheets/application.css.scss
	```

	```app/assets/stylesheets/application.css.scss
	@import "bootstrap-sprockets";
	@import "bootstrap";
	@import "font-awesome-sprockets";
	@import "font-awesome";
	```

	> 行の順番を入れ替えると動かないので注意！

- 既存の `app/assets/stylesheets/application.css` は削除。

	```shell
	$ rm app/assets/stylesheets/application.css
	```

- `app/assets/javascripts/application.js` の修正。

	```app/assets/javascripts/application.js
	//= require bootstrap-sprockets ←この行を追記
	```

以上で環境構築は完了。

ちなみに、Git 管理化から除外しておくものは次のとおり。

```:.gitigunore
/vendor/bundle
/.idea ← IDE に RubyMine を使っている場合
```

# 参考：動作確認の方法

## ① とりあえず適当に Scaffold

```shell:
$ ./bin/rails g scaffold person name:string age:integer memo:text
```

```shell:
$ ./bin/rake db:create（もし作成されていない場合）
$ ./bin/rake db:migrate
```

## ② Bootstrap & Font Awesome の動作確認

- 共通ページレイアウトを修正。

	```haml:app/views/layouts/application.html.haml
	!!!
	%html
	  %head
	    %title HogeApp
	    = stylesheet_link_tag    'application', media: 'all'
	    = javascript_include_tag 'application'
	    = csrf_meta_tags
	  %body
	    %nav.navbar.navbar-default{role: "navigation"}
	      .container-fluid
	        .navbar-header
	          %a.navbar-brand{href: "#"}
	            %i.fa.fa-home
	    .container
	      = yield
	```

- 表示を確認。

	```shell:
	$ ./bin/rails s
	```

	ブラウザで `http://127.0.0.1:3000/people` にアクセス。

	![スクリーンショット 2014-10-03 19.38.05.png](https://qiita-image-store.s3.amazonaws.com/0/35733/498a144b-fc6c-fd00-587d-c85f1d6f6a95.png "スクリーンショット 2014-10-03 19.38.05.png")

## ③ Knockout.js の動作確認

### View

```haml:app/views/people/index.html.haml
〜

#ItemView
  %p
    ほげほげ：
    %input{"data-bind" => "value: hoge, valueUpdate: 'afterkeydown'"}
  %p
    %span{"data-bind" => "text: hoge"}

  :coffee
    $ ->
      ko.applyBindings new HOGEAPP_PEOPLE.ItemViewModel(), $("#ItemView")[0]
```

### ViewModel

```coffeescript:app/assets/javascripts/people.js.coffee
$ ->
  HOGEAPP_PEOPLE = window.HOGEAPP_PEOPLE = window.HOGEAPP_PEOPLE ? {}

  HOGEAPP_PEOPLE.ItemViewModel = () ->
    @hoge = ko.observable()
    return

  return
```

次のようにデータバインドが動いていればOK。

![スクリーンショット 2014-10-03 20.17.58.png](https://qiita-image-store.s3.amazonaws.com/0/35733/420f716c-e3b7-caf1-0f9c-9c91355a08e3.png "スクリーンショット 2014-10-03 20.17.58.png")

〜以上〜