Rails + AdminLTE(Bootstrap3) with bower-rails

[AdminLTE](https://almsaeedstudio.com/)テンプレートを使ってRailsアプリを作ったのでメモ。

AdminLTEはオープンソースのBootstrap3ベースのcssテンプレート。管理画面やダッシュボード向けのデザイン。[Cookpad開発者ブログ - 新規サービスの管理画面を短期間で見栄え良く実装する](http://techlife.cookpad.com/entry/2015/04/06/155940)で紹介されてたので使ってみてるところ。


# 方針など

AdminLTEはbowerで管理。railsでは[bower-rails](https://github.com/rharriso/bower-rails)というgemがあるのでこれを使う。なお、[adminlte-rails](https://github.com/shine60vn/adminlte-rails)というgemも検討したがこちらは対応AdminLTEのバージョンが古いため使わないことにした。

# 手順

## rails new

```
$ rails new MyToDo  --skip-turbolinks
$ cd MyToDo
$ rails g scaffold tasks title:string done:boolean
$ rake db:migrate
```

## slim

```ruby:Gemfile
gem 'slim-rails'
```

適宜.erbのファイルは.slimに変換する

## bowerでAdminLTEをインストール

```ruby:Gemfile
gem "bower-rails"
```

```ruby:Bowerfile
asset "admin-lte", '2.0.5'
```

```
$ rake bower:install  
$ echo /vendor/assets/bower_components >> .gitignore
```

vendor/assets/bower_components/admin-lte/ 以下にassetがインストールされる~~ので、このパスを`config/application.rb`に`config.assets.paths << Rails.root.join('vendor', 'assets', 'bower_components')`のように追加する。これは後の手順でapplication.css.scssからの参照、`image_path()`ヘルパーなどで使うため必要。~~ **UPDATE: 必要なかった。パスは自動的に追加される** 

FYI: asset pathはrails consoleで確かめれる。

```bash
$ rails c
Loading development environment (Rails 4.2.1)
irb(main):001:0> pp  Rails.application.config.assets.paths ;nil
["/Users/nikushi/src/github.com/niku4i/angular-todo-test/app/assets/images",
 "/Users/nikushi/src/github.com/niku4i/angular-todo-test/app/assets/javascripts",
 "/Users/nikushi/src/github.com/niku4i/angular-todo-test/app/assets/stylesheets",
 "/Users/nikushi/src/github.com/niku4i/angular-todo-test/vendor/assets/bower_components",
 "/Users/nikushi/src/github.com/niku4i/angular-todo-test/vendor/assets/javascripts",
 "/Users/nikushi/src/github.com/niku4i/angular-todo-test/vendor/assets/stylesheets",
 "/Users/nikushi/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/jquery-rails-4.0.3/vendor/assets/javascripts",
 "/Users/nikushi/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/coffee-rails-4.1.0/lib/assets/javascripts",
 #<Pathname:/Users/nikushi/src/github.com/niku4i/angular-todo-test/vendor/assets/bower_components>]
=> nil
```

## application.js && application.css.scss

cssをsassで書けるようにしておく。

```
$ git mv app/assets/stylesheets/application.css app/assets/stylesheets/application.css.scss 
```

application.css.scssへ必要なassetを記述。admin-lteの中にbootstrapもバンドルされているので別途bootstrapをインストールする必要はない。application.css.scssに書けばOK。

```diff:app/assets/stylesheets/application.css.scss
+ *= require admin-lte/bootstrap/css/bootstrap
+ *= require admin-lte/dist/css/AdminLTE
+ *= require admin-lte/dist/css/skins/skin-blue
 *= require_self
 */
```


application.jsを修正する。バンドルされたbootstrapとadminlteのjsを呼び出す。

```diff:app/assets/javascripts/application.js
 //= require jquery
 //= require jquery_ujs
+//= require admin-lte/bootstrap/js/bootstrap
+//= require admin-lte/dist/js/app.js
 //= require_tree .
```

## layout

拡張子はslimを使うので変えておく。

```
$ git mv app/views/layouts/application.html.erb app/views/layouts/application.html.slim
```

AdminLTEには[starter template](https://almsaeedstudio.com/themes/AdminLTE/starter.html)が用意されているのでこれを使う。wgetかcurlでdownloadしてhtmlをクリップボードにコピーした後、[html2slim](https://html2slim.herokuapp.com/)でslimに変換したらいい感じ変換される。便利。application.html.slimを更新する。あとは、main contentを呼び出すところで、`= yield`書けばOK。

なお、fontawesomeとioniciconsはとりあえず以下のようにCDNから参照させるようにした。

```html:app/assets/javascripts/application.js
stylesheet_link_tag "https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"
stylesheet_link_tag "http://code.ionicframework.com/ionicons/2.0.0/css/ionicons.min.css"
```

また、bower経由でインストールするので、start layoutのサンプル画像のパスを修正する必要がある。imgタグのsrc属性を`src="#{image_path('admin-lte/dist/img/user2-160x160.jpg')}"`こういうふうに書き換える。

できたslimファイルはこちら => [検証で作ったToDOアプリのlayoutファイル](https://github.com/niku4i/angularjs-todo-test/blob/45e1567ff2d7ab6ad66a03d4fec02f1600861007/app/views/layouts/application.html.slim) 参考までに。

## Railsの設定

`rails s`してページアクセスすると以下のエラーが出る。

```
Sprockets::Rails::Helper::AssetFilteredError in Tasks#index

Asset filtered out and will not be served: add `Rails.application.config.assets.precompile += %w( admin-lte/dist/img/user2-160x160.jpg )` to `config/initializers/assets.rb` and restart your server
```

RAILS_ENV=developmentで画面表示する際に動的にprecompileが実行される。その際にprecompile対象のパスにadmin-lte/以下が含まれていないためこうなる。

~~これを回避するために以下を入れた。(これでいいんだっけ?、とりあえずこれで動く。)~~ 

```ruby:config/environments/development.rb
config.assets.raise_runtime_errors = false
```

**↑のworkaroundではなく**下のとおりやる

```diff:/environments/development.rb
   # Adds additional error checking when serving assets at runtime.
   # Checks for improperly declared sprockets dependencies.
   # Raises helpful error messages.
-  config.assets.raise_runtime_errors = false
+  config.assets.raise_runtime_errors = true
```


serverをリスタートすると http://localhost:3000/tasks にきれいなページが表示される。


# はまったところ

このようにまとめると大した手順ではないが、ここまで来るのに結構時間がかかった。はまった点も書いておく。

* 最初[adminlte-rails](https://github.com/shine60vn/adminlte-rails)を使って進めていたがadminlte-railsは古くて使えない判断するまでに時間がかかった。AdminLTEの[documentaion](https://almsaeedstudio.com/themes/AdminLTE/documentation/index.html)のとおりstarter layoutを使ってみたが動かなくて、AdminLTEはversion 2系だったが、adminlte-railsは1.3のコードだった。よってgemは介さずbowerを使う方針転換。

# 参考

[検証で書いたToDoアプリのリポジトリ](https://github.com/niku4i/angularjs-todo-test)