Rails4 asset pipeline関連設定まとめ（Heroku対応込）


rails4のasset pipeline関連の設定で色々ハマってしまったので、herokuにデプロイして動くように、かつローカルのproductionモードでの起動でも動くように設定した内容をまとめてみます。

# 環境（設定に関係のあるもの）
- rails 4.1.10
- active_admin 1.0.0pre
- font-awesome-rails 4.2.0.0


# 基本の設定

```ruby:config/environment/production.rb
# Disable Rails's static asset server (Apache or nginx will already do this).
config.serve_static_assets = true # rails4.1以前
config.serve_static_files = true # rails4.2〜
config.public_file_server.enabled = true # rails5〜
```
herokuに上げたりproductionで起動した時に、画像が読み込まれない！となったら大体ここが原因と思われます。

**注意** railsのバージョンによってここの名前が変わっています。

[railsガイド](http://railsguides.jp/asset_pipeline.html)によると
> config.serve_static_assetsがtrueに設定されていると、publicディレクトリ以下に置かれているあらゆるアセットはアプリケーションまたはWebサーバーによって静的なファイルとして取り扱われます。

とのことです。

herokuではこれをtrueにしてねと書いてありました。
参考：[Rails4 Asset Pipeline on Heroku](https://devcenter.heroku.com/articles/rails-4-asset-pipeline)

development.rbのconfig.serve_static_assetsもtrueにしておくのを忘れてpublic以下の画像が表示されないというアホなミスをしてしまったのは私です。どうぞお気をつけを。

```ruby:
# Compress JavaScripts and CSS.
config.assets.js_compressor = :uglifier
config.assets.css_compressor = :scss
```
jsとcssの圧縮。config.assets.css_compressorはデフォルトではコメントアウトされてたので:sassなり:yuiなり適宜設定してあげないとcssがコンパイルされず読み込まれません。


```ruby:
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = true
```
assetファイルは事前にコンパイルしておきますが、もしassetファイルが見つからなかった場合にこれをtrueにしておくとサーバー側でコンパイルしてくれます。ただし、コンパイルによりサーバー側の負荷も上がるのでtrue/falseどちらにするかは状況と好みによりけり。


```ruby:
# Generate digests for assets URLs.
config.assets.digest = true
```
assetファイル名にハッシュをつけます。こんな感じ→_base-4330800e96dd94c86b5e62bfc49d2213.css。
ハッシュをつけたくなければfalseに。


# assetファイルのコンパイル
コンソールで以下のコマンドを叩いてapp/assets以下のファイルをコンパイルします。

```
RAILS_ENV=production bundle exec rake assets:precompile assets:clean
```

RAILS_ENV=productionを入れないとproductionモードで起動した時にうまく表示されないことがあるようです。
assets:cleanも一緒に入れておくと古いファイルも消しておいてくれて便利。

# 古いassetファイルの削除
```
bundle exec rake assets:clean
```
過去のバージョンのassetファイルを削除してくれます。ただし、直近３バージョンは保持する仕様になっているようでなので旧バージョンファイルが１世代前とかしかないとファイルは残ってます。

```
bundle exec rake assets:clobber
```
そのプロジェクトのassetファイルをすべて消します。やってみたら、public/assets以下がごっそりなくなりました。完全にやり直したいとき向け。

# asset pipelineを使わない
```ruby:config/environment/development.rb
config.assets.enabled = false
```
developmentモードではasset pipeline使ってるとcss更新したりした時にすぐに確認できないのでオフにしておいた方が良かったり。

# asset pipelineまわりで起こりがちなこと
### background-imageが表示されない
こちらが参考になりました。→ [Rails4ではbackground:url("assets/hoge.png")の書き方は動かない話](http://qiita.com/wadako111/items/03bc00d914e62243a511)
自分もpublic/images以下に画像ファイルを置くことで解決しました。
capistranoを使っていなかったのでpublic/assets以下でも良かったのですが、public/images以下にする方が膨大なcssやjsのアセットファイルに画像ファイルが埋もれずに済むのでこちらの方法にしました。

### ローカルでprecompileするとdevelopment環境でアセットが更新されない

この問題は色々試してみたのですが、設定をいじってもなんだかうまくいかず自分の中でまだいい結論が出ていないので、参考のページだけはらせていただきます。

参考：
[Rails 3.2 アセットパイプラインで開発環境でアセットが更新されない](http://bokukoko.hatenablog.com/entry/20120503/1336000017)
[development環境下でprecompileすると，以降developmentでassetsが上手く読み込まれない](http://blog.interfirm.co.jp/entry/2014/10/24/131503)
### font-awesomeのフォントが表示されない
フォントファイルがプリコンパイルされるようにproduction.rbまたはapplication.rbに以下の一行を追加。

```ruby:production.rb
config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/ 
```
### Icomoonのフォントが表示されない
`src:url('icomoon.eot');`を`src:font-url('icomoon.eot');`に変更しました。
@font-faceの設定は以下のようになっています。

```scss:icomoon.scss
@font-face {
	font-family: 'icomoon';
	src:font-url('icomoon.eot');
	src:font-url('icomoon.eot?#iefix') format('embedded-opentype'),
		font-url('icomoon.woff') format('woff'),
		font-url('icomoon.ttf') format('truetype'),
		font-url('icomoon.svg#icomoon') format('svg');
	font-weight: normal;
	font-style: normal;
}
```


# 参考サイト
- [アセットパイプライン|Railsガイド](http://railsguides.jp/asset_pipeline.html)
- [5分でわかる!? アセットパイプライン（Assets Pipeline）](http://rails.hatenadiary.jp/entry/2013/03/03/125801)
- [アセットパイプライン|Rails日本語ドキュメント|Ruby STUDIO](http://ruby.studio-kingdom.com/rails/guides/asset_pipeline)