rails 3.2.22.2 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (216) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +85 -0
  3. data/guides/CHANGELOG.md +31 -0
  4. data/guides/Rakefile +79 -0
  5. data/guides/assets/images/akshaysurve.jpg +0 -0
  6. data/guides/assets/images/belongs_to.png +0 -0
  7. data/guides/assets/images/book_icon.gif +0 -0
  8. data/guides/assets/images/bullet.gif +0 -0
  9. data/guides/assets/images/chapters_icon.gif +0 -0
  10. data/guides/assets/images/check_bullet.gif +0 -0
  11. data/guides/assets/images/credits_pic_blank.gif +0 -0
  12. data/guides/assets/images/csrf.png +0 -0
  13. data/guides/assets/images/edge_badge.png +0 -0
  14. data/guides/assets/images/favicon.ico +0 -0
  15. data/guides/assets/images/feature_tile.gif +0 -0
  16. data/guides/assets/images/footer_tile.gif +0 -0
  17. data/guides/assets/images/fxn.png +0 -0
  18. data/guides/assets/images/getting_started/article_with_comments.png +0 -0
  19. data/guides/assets/images/getting_started/challenge.png +0 -0
  20. data/guides/assets/images/getting_started/confirm_dialog.png +0 -0
  21. data/guides/assets/images/getting_started/forbidden_attributes_for_new_article.png +0 -0
  22. data/guides/assets/images/getting_started/form_with_errors.png +0 -0
  23. data/guides/assets/images/getting_started/index_action_with_edit_link.png +0 -0
  24. data/guides/assets/images/getting_started/new_article.png +0 -0
  25. data/guides/assets/images/getting_started/rails_welcome.png +0 -0
  26. data/guides/assets/images/getting_started/routing_error_no_controller.png +0 -0
  27. data/guides/assets/images/getting_started/routing_error_no_route_matches.png +0 -0
  28. data/guides/assets/images/getting_started/show_action_for_articles.png +0 -0
  29. data/guides/assets/images/getting_started/template_is_missing_articles_new.png +0 -0
  30. data/guides/assets/images/getting_started/unknown_action_create_for_articles.png +0 -0
  31. data/guides/assets/images/getting_started/unknown_action_new_for_articles.png +0 -0
  32. data/guides/assets/images/grey_bullet.gif +0 -0
  33. data/guides/assets/images/habtm.png +0 -0
  34. data/guides/assets/images/has_many.png +0 -0
  35. data/guides/assets/images/has_many_through.png +0 -0
  36. data/guides/assets/images/has_one.png +0 -0
  37. data/guides/assets/images/has_one_through.png +0 -0
  38. data/guides/assets/images/header_backdrop.png +0 -0
  39. data/guides/assets/images/header_tile.gif +0 -0
  40. data/guides/assets/images/i18n/demo_html_safe.png +0 -0
  41. data/guides/assets/images/i18n/demo_localized_pirate.png +0 -0
  42. data/guides/assets/images/i18n/demo_translated_en.png +0 -0
  43. data/guides/assets/images/i18n/demo_translated_pirate.png +0 -0
  44. data/guides/assets/images/i18n/demo_translation_missing.png +0 -0
  45. data/guides/assets/images/i18n/demo_untranslated.png +0 -0
  46. data/guides/assets/images/icons/README +5 -0
  47. data/guides/assets/images/icons/callouts/1.png +0 -0
  48. data/guides/assets/images/icons/callouts/10.png +0 -0
  49. data/guides/assets/images/icons/callouts/11.png +0 -0
  50. data/guides/assets/images/icons/callouts/12.png +0 -0
  51. data/guides/assets/images/icons/callouts/13.png +0 -0
  52. data/guides/assets/images/icons/callouts/14.png +0 -0
  53. data/guides/assets/images/icons/callouts/15.png +0 -0
  54. data/guides/assets/images/icons/callouts/2.png +0 -0
  55. data/guides/assets/images/icons/callouts/3.png +0 -0
  56. data/guides/assets/images/icons/callouts/4.png +0 -0
  57. data/guides/assets/images/icons/callouts/5.png +0 -0
  58. data/guides/assets/images/icons/callouts/6.png +0 -0
  59. data/guides/assets/images/icons/callouts/7.png +0 -0
  60. data/guides/assets/images/icons/callouts/8.png +0 -0
  61. data/guides/assets/images/icons/callouts/9.png +0 -0
  62. data/guides/assets/images/icons/caution.png +0 -0
  63. data/guides/assets/images/icons/example.png +0 -0
  64. data/guides/assets/images/icons/home.png +0 -0
  65. data/guides/assets/images/icons/important.png +0 -0
  66. data/guides/assets/images/icons/next.png +0 -0
  67. data/guides/assets/images/icons/note.png +0 -0
  68. data/guides/assets/images/icons/prev.png +0 -0
  69. data/guides/assets/images/icons/tip.png +0 -0
  70. data/guides/assets/images/icons/up.png +0 -0
  71. data/guides/assets/images/icons/warning.png +0 -0
  72. data/guides/assets/images/nav_arrow.gif +0 -0
  73. data/guides/assets/images/oscardelben.jpg +0 -0
  74. data/guides/assets/images/polymorphic.png +0 -0
  75. data/guides/assets/images/radar.png +0 -0
  76. data/guides/assets/images/rails4_features.png +0 -0
  77. data/guides/assets/images/rails_guides_kindle_cover.jpg +0 -0
  78. data/guides/assets/images/rails_guides_logo.gif +0 -0
  79. data/guides/assets/images/rails_logo_remix.gif +0 -0
  80. data/guides/assets/images/session_fixation.png +0 -0
  81. data/guides/assets/images/tab_grey.gif +0 -0
  82. data/guides/assets/images/tab_info.gif +0 -0
  83. data/guides/assets/images/tab_note.gif +0 -0
  84. data/guides/assets/images/tab_red.gif +0 -0
  85. data/guides/assets/images/tab_yellow.gif +0 -0
  86. data/guides/assets/images/tab_yellow.png +0 -0
  87. data/guides/assets/images/vijaydev.jpg +0 -0
  88. data/guides/assets/javascripts/guides.js +59 -0
  89. data/guides/assets/javascripts/jquery.min.js +4 -0
  90. data/guides/assets/javascripts/responsive-tables.js +43 -0
  91. data/guides/assets/javascripts/syntaxhighlighter/shBrushAS3.js +59 -0
  92. data/guides/assets/javascripts/syntaxhighlighter/shBrushAppleScript.js +75 -0
  93. data/guides/assets/javascripts/syntaxhighlighter/shBrushBash.js +59 -0
  94. data/guides/assets/javascripts/syntaxhighlighter/shBrushCSharp.js +65 -0
  95. data/guides/assets/javascripts/syntaxhighlighter/shBrushColdFusion.js +100 -0
  96. data/guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js +97 -0
  97. data/guides/assets/javascripts/syntaxhighlighter/shBrushCss.js +91 -0
  98. data/guides/assets/javascripts/syntaxhighlighter/shBrushDelphi.js +55 -0
  99. data/guides/assets/javascripts/syntaxhighlighter/shBrushDiff.js +41 -0
  100. data/guides/assets/javascripts/syntaxhighlighter/shBrushErlang.js +52 -0
  101. data/guides/assets/javascripts/syntaxhighlighter/shBrushGroovy.js +67 -0
  102. data/guides/assets/javascripts/syntaxhighlighter/shBrushJScript.js +52 -0
  103. data/guides/assets/javascripts/syntaxhighlighter/shBrushJava.js +57 -0
  104. data/guides/assets/javascripts/syntaxhighlighter/shBrushJavaFX.js +58 -0
  105. data/guides/assets/javascripts/syntaxhighlighter/shBrushPerl.js +72 -0
  106. data/guides/assets/javascripts/syntaxhighlighter/shBrushPhp.js +88 -0
  107. data/guides/assets/javascripts/syntaxhighlighter/shBrushPlain.js +33 -0
  108. data/guides/assets/javascripts/syntaxhighlighter/shBrushPowerShell.js +74 -0
  109. data/guides/assets/javascripts/syntaxhighlighter/shBrushPython.js +64 -0
  110. data/guides/assets/javascripts/syntaxhighlighter/shBrushRuby.js +55 -0
  111. data/guides/assets/javascripts/syntaxhighlighter/shBrushSass.js +94 -0
  112. data/guides/assets/javascripts/syntaxhighlighter/shBrushScala.js +51 -0
  113. data/guides/assets/javascripts/syntaxhighlighter/shBrushSql.js +66 -0
  114. data/guides/assets/javascripts/syntaxhighlighter/shBrushVb.js +56 -0
  115. data/guides/assets/javascripts/syntaxhighlighter/shBrushXml.js +69 -0
  116. data/guides/assets/javascripts/syntaxhighlighter/shCore.js +17 -0
  117. data/guides/assets/stylesheets/fixes.css +16 -0
  118. data/guides/assets/stylesheets/kindle.css +11 -0
  119. data/guides/assets/stylesheets/main.css +713 -0
  120. data/guides/assets/stylesheets/print.css +52 -0
  121. data/guides/assets/stylesheets/reset.css +43 -0
  122. data/guides/assets/stylesheets/responsive-tables.css +50 -0
  123. data/guides/assets/stylesheets/style.css +13 -0
  124. data/guides/assets/stylesheets/syntaxhighlighter/shCore.css +226 -0
  125. data/guides/assets/stylesheets/syntaxhighlighter/shCoreDefault.css +328 -0
  126. data/guides/assets/stylesheets/syntaxhighlighter/shCoreDjango.css +331 -0
  127. data/guides/assets/stylesheets/syntaxhighlighter/shCoreEclipse.css +339 -0
  128. data/guides/assets/stylesheets/syntaxhighlighter/shCoreEmacs.css +324 -0
  129. data/guides/assets/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css +328 -0
  130. data/guides/assets/stylesheets/syntaxhighlighter/shCoreMDUltra.css +324 -0
  131. data/guides/assets/stylesheets/syntaxhighlighter/shCoreMidnight.css +324 -0
  132. data/guides/assets/stylesheets/syntaxhighlighter/shCoreRDark.css +324 -0
  133. data/guides/assets/stylesheets/syntaxhighlighter/shThemeDefault.css +117 -0
  134. data/guides/assets/stylesheets/syntaxhighlighter/shThemeDjango.css +120 -0
  135. data/guides/assets/stylesheets/syntaxhighlighter/shThemeEclipse.css +128 -0
  136. data/guides/assets/stylesheets/syntaxhighlighter/shThemeEmacs.css +113 -0
  137. data/guides/assets/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css +117 -0
  138. data/guides/assets/stylesheets/syntaxhighlighter/shThemeMDUltra.css +113 -0
  139. data/guides/assets/stylesheets/syntaxhighlighter/shThemeMidnight.css +113 -0
  140. data/guides/assets/stylesheets/syntaxhighlighter/shThemeRDark.css +113 -0
  141. data/guides/assets/stylesheets/syntaxhighlighter/shThemeRailsGuides.css +116 -0
  142. data/guides/bug_report_templates/action_controller_gem.rb +47 -0
  143. data/guides/bug_report_templates/action_controller_master.rb +54 -0
  144. data/guides/bug_report_templates/active_record_gem.rb +40 -0
  145. data/guides/bug_report_templates/active_record_master.rb +49 -0
  146. data/guides/rails_guides/generator.rb +248 -0
  147. data/guides/rails_guides/helpers.rb +53 -0
  148. data/guides/rails_guides/indexer.rb +68 -0
  149. data/guides/rails_guides/kindle.rb +119 -0
  150. data/guides/rails_guides/levenshtein.rb +39 -0
  151. data/guides/rails_guides/markdown/renderer.rb +82 -0
  152. data/guides/rails_guides/markdown.rb +167 -0
  153. data/guides/rails_guides.rb +63 -0
  154. data/guides/source/2_2_release_notes.md +435 -0
  155. data/guides/source/2_3_release_notes.md +621 -0
  156. data/guides/source/3_0_release_notes.md +611 -0
  157. data/guides/source/3_1_release_notes.md +559 -0
  158. data/guides/source/3_2_release_notes.md +568 -0
  159. data/guides/source/4_0_release_notes.md +279 -0
  160. data/guides/source/4_1_release_notes.md +730 -0
  161. data/guides/source/4_2_release_notes.md +850 -0
  162. data/guides/source/_license.html.erb +2 -0
  163. data/guides/source/_welcome.html.erb +19 -0
  164. data/guides/source/action_controller_overview.md +1249 -0
  165. data/guides/source/action_mailer_basics.md +752 -0
  166. data/guides/source/action_view_overview.md +1620 -0
  167. data/guides/source/active_job_basics.md +318 -0
  168. data/guides/source/active_model_basics.md +554 -0
  169. data/guides/source/active_record_basics.md +374 -0
  170. data/guides/source/active_record_callbacks.md +413 -0
  171. data/guides/source/active_record_migrations.md +1018 -0
  172. data/guides/source/active_record_postgresql.md +433 -0
  173. data/guides/source/active_record_querying.md +1783 -0
  174. data/guides/source/active_record_validations.md +1178 -0
  175. data/guides/source/active_support_core_extensions.md +3904 -0
  176. data/guides/source/active_support_instrumentation.md +499 -0
  177. data/guides/source/api_documentation_guidelines.md +361 -0
  178. data/guides/source/asset_pipeline.md +1360 -0
  179. data/guides/source/association_basics.md +2236 -0
  180. data/guides/source/caching_with_rails.md +379 -0
  181. data/guides/source/command_line.md +625 -0
  182. data/guides/source/configuring.md +1045 -0
  183. data/guides/source/constant_autoloading_and_reloading.md +1297 -0
  184. data/guides/source/contributing_to_ruby_on_rails.md +624 -0
  185. data/guides/source/credits.html.erb +80 -0
  186. data/guides/source/debugging_rails_applications.md +861 -0
  187. data/guides/source/development_dependencies_install.md +289 -0
  188. data/guides/source/documents.yaml +205 -0
  189. data/guides/source/engines.md +1412 -0
  190. data/guides/source/form_helpers.md +1024 -0
  191. data/guides/source/generators.md +676 -0
  192. data/guides/source/getting_started.md +2085 -0
  193. data/guides/source/i18n.md +1086 -0
  194. data/guides/source/index.html.erb +28 -0
  195. data/guides/source/initialization.md +704 -0
  196. data/guides/source/kindle/copyright.html.erb +1 -0
  197. data/guides/source/kindle/layout.html.erb +27 -0
  198. data/guides/source/kindle/rails_guides.opf.erb +52 -0
  199. data/guides/source/kindle/toc.html.erb +24 -0
  200. data/guides/source/kindle/toc.ncx.erb +64 -0
  201. data/guides/source/kindle/welcome.html.erb +5 -0
  202. data/guides/source/layout.html.erb +143 -0
  203. data/guides/source/layouts_and_rendering.md +1227 -0
  204. data/guides/source/maintenance_policy.md +78 -0
  205. data/guides/source/nested_model_forms.md +228 -0
  206. data/guides/source/plugins.md +444 -0
  207. data/guides/source/rails_application_templates.md +266 -0
  208. data/guides/source/rails_on_rack.md +336 -0
  209. data/guides/source/routing.md +1141 -0
  210. data/guides/source/ruby_on_rails_guides_guidelines.md +127 -0
  211. data/guides/source/security.md +1024 -0
  212. data/guides/source/testing.md +1123 -0
  213. data/guides/source/upgrading_ruby_on_rails.md +1154 -0
  214. data/guides/source/working_with_javascript_in_rails.md +407 -0
  215. data/guides/w3c_validator.rb +97 -0
  216. metadata +290 -44
@@ -0,0 +1,1360 @@
1
+ The Asset Pipeline
2
+ ==================
3
+
4
+ This guide covers the asset pipeline.
5
+
6
+ After reading this guide, you will know:
7
+
8
+ * What the asset pipeline is and what it does.
9
+ * How to properly organize your application assets.
10
+ * The benefits of the asset pipeline.
11
+ * How to add a pre-processor to the pipeline.
12
+ * How to package assets with a gem.
13
+
14
+ --------------------------------------------------------------------------------
15
+
16
+ What is the Asset Pipeline?
17
+ ---------------------------
18
+
19
+ The asset pipeline provides a framework to concatenate and minify or compress
20
+ JavaScript and CSS assets. It also adds the ability to write these assets in
21
+ other languages and pre-processors such as CoffeeScript, Sass and ERB.
22
+
23
+ The asset pipeline is technically no longer a core feature of Rails 4, it has
24
+ been extracted out of the framework into the
25
+ [sprockets-rails](https://github.com/rails/sprockets-rails) gem.
26
+
27
+ The asset pipeline is enabled by default.
28
+
29
+ You can disable the asset pipeline while creating a new application by
30
+ passing the `--skip-sprockets` option.
31
+
32
+ ```bash
33
+ rails new appname --skip-sprockets
34
+ ```
35
+
36
+ Rails 4 automatically adds the `sass-rails`, `coffee-rails` and `uglifier`
37
+ gems to your Gemfile, which are used by Sprockets for asset compression:
38
+
39
+ ```ruby
40
+ gem 'sass-rails'
41
+ gem 'uglifier'
42
+ gem 'coffee-rails'
43
+ ```
44
+
45
+ Using the `--skip-sprockets` option will prevent Rails 4 from adding
46
+ `sass-rails` and `uglifier` to Gemfile, so if you later want to enable
47
+ the asset pipeline you will have to add those gems to your Gemfile. Also,
48
+ creating an application with the `--skip-sprockets` option will generate
49
+ a slightly different `config/application.rb` file, with a require statement
50
+ for the sprockets railtie that is commented-out. You will have to remove
51
+ the comment operator on that line to later enable the asset pipeline:
52
+
53
+ ```ruby
54
+ # require "sprockets/railtie"
55
+ ```
56
+
57
+ To set asset compression methods, set the appropriate configuration options
58
+ in `production.rb` - `config.assets.css_compressor` for your CSS and
59
+ `config.assets.js_compressor` for your JavaScript:
60
+
61
+ ```ruby
62
+ config.assets.css_compressor = :yui
63
+ config.assets.js_compressor = :uglifier
64
+ ```
65
+
66
+ NOTE: The `sass-rails` gem is automatically used for CSS compression if included
67
+ in Gemfile and no `config.assets.css_compressor` option is set.
68
+
69
+
70
+ ### Main Features
71
+
72
+ The first feature of the pipeline is to concatenate assets, which can reduce the
73
+ number of requests that a browser makes to render a web page. Web browsers are
74
+ limited in the number of requests that they can make in parallel, so fewer
75
+ requests can mean faster loading for your application.
76
+
77
+ Sprockets concatenates all JavaScript files into one master `.js` file and all
78
+ CSS files into one master `.css` file. As you'll learn later in this guide, you
79
+ can customize this strategy to group files any way you like. In production,
80
+ Rails inserts an MD5 fingerprint into each filename so that the file is cached
81
+ by the web browser. You can invalidate the cache by altering this fingerprint,
82
+ which happens automatically whenever you change the file contents.
83
+
84
+ The second feature of the asset pipeline is asset minification or compression.
85
+ For CSS files, this is done by removing whitespace and comments. For JavaScript,
86
+ more complex processes can be applied. You can choose from a set of built in
87
+ options or specify your own.
88
+
89
+ The third feature of the asset pipeline is it allows coding assets via a
90
+ higher-level language, with precompilation down to the actual assets. Supported
91
+ languages include Sass for CSS, CoffeeScript for JavaScript, and ERB for both by
92
+ default.
93
+
94
+ ### What is Fingerprinting and Why Should I Care?
95
+
96
+ Fingerprinting is a technique that makes the name of a file dependent on the
97
+ contents of the file. When the file contents change, the filename is also
98
+ changed. For content that is static or infrequently changed, this provides an
99
+ easy way to tell whether two versions of a file are identical, even across
100
+ different servers or deployment dates.
101
+
102
+ When a filename is unique and based on its content, HTTP headers can be set to
103
+ encourage caches everywhere (whether at CDNs, at ISPs, in networking equipment,
104
+ or in web browsers) to keep their own copy of the content. When the content is
105
+ updated, the fingerprint will change. This will cause the remote clients to
106
+ request a new copy of the content. This is generally known as _cache busting_.
107
+
108
+ The technique sprockets uses for fingerprinting is to insert a hash of the
109
+ content into the name, usually at the end. For example a CSS file `global.css`
110
+
111
+ ```
112
+ global-908e25f4bf641868d8683022a5b62f54.css
113
+ ```
114
+
115
+ This is the strategy adopted by the Rails asset pipeline.
116
+
117
+ Rails' old strategy was to append a date-based query string to every asset linked
118
+ with a built-in helper. In the source the generated code looked like this:
119
+
120
+ ```
121
+ /stylesheets/global.css?1309495796
122
+ ```
123
+
124
+ The query string strategy has several disadvantages:
125
+
126
+ 1. **Not all caches will reliably cache content where the filename only differs by
127
+ query parameters**
128
+
129
+ [Steve Souders recommends](http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/),
130
+ "...avoiding a querystring for cacheable resources". He found that in this
131
+ case 5-20% of requests will not be cached. Query strings in particular do not
132
+ work at all with some CDNs for cache invalidation.
133
+
134
+ 2. **The file name can change between nodes in multi-server environments.**
135
+
136
+ The default query string in Rails 2.x is based on the modification time of
137
+ the files. When assets are deployed to a cluster, there is no guarantee that the
138
+ timestamps will be the same, resulting in different values being used depending
139
+ on which server handles the request.
140
+
141
+ 3. **Too much cache invalidation**
142
+
143
+ When static assets are deployed with each new release of code, the mtime
144
+ (time of last modification) of _all_ these files changes, forcing all remote
145
+ clients to fetch them again, even when the content of those assets has not changed.
146
+
147
+ Fingerprinting fixes these problems by avoiding query strings, and by ensuring
148
+ that filenames are consistent based on their content.
149
+
150
+ Fingerprinting is enabled by default for production and disabled for all other
151
+ environments. You can enable or disable it in your configuration through the
152
+ `config.assets.digest` option.
153
+
154
+ More reading:
155
+
156
+ * [Optimize caching](http://code.google.com/speed/page-speed/docs/caching.html)
157
+ * [Revving Filenames: don't use querystring](http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/)
158
+
159
+
160
+ How to Use the Asset Pipeline
161
+ -----------------------------
162
+
163
+ In previous versions of Rails, all assets were located in subdirectories of
164
+ `public` such as `images`, `javascripts` and `stylesheets`. With the asset
165
+ pipeline, the preferred location for these assets is now the `app/assets`
166
+ directory. Files in this directory are served by the Sprockets middleware.
167
+
168
+ Assets can still be placed in the `public` hierarchy. Any assets under `public`
169
+ will be served as static files by the application or web server when
170
+ `config.serve_static_files` is set to true. You should use `app/assets` for
171
+ files that must undergo some pre-processing before they are served.
172
+
173
+ In production, Rails precompiles these files to `public/assets` by default. The
174
+ precompiled copies are then served as static assets by the web server. The files
175
+ in `app/assets` are never served directly in production.
176
+
177
+ ### Controller Specific Assets
178
+
179
+ When you generate a scaffold or a controller, Rails also generates a JavaScript
180
+ file (or CoffeeScript file if the `coffee-rails` gem is in the `Gemfile`) and a
181
+ Cascading Style Sheet file (or SCSS file if `sass-rails` is in the `Gemfile`)
182
+ for that controller. Additionally, when generating a scaffold, Rails generates
183
+ the file scaffolds.css (or scaffolds.css.scss if `sass-rails` is in the
184
+ `Gemfile`.)
185
+
186
+ For example, if you generate a `ProjectsController`, Rails will also add a new
187
+ file at `app/assets/javascripts/projects.js.coffee` and another at
188
+ `app/assets/stylesheets/projects.css.scss`. By default these files will be ready
189
+ to use by your application immediately using the `require_tree` directive. See
190
+ [Manifest Files and Directives](#manifest-files-and-directives) for more details
191
+ on require_tree.
192
+
193
+ You can also opt to include controller specific stylesheets and JavaScript files
194
+ only in their respective controllers using the following:
195
+
196
+ `<%= javascript_include_tag params[:controller] %>` or `<%= stylesheet_link_tag
197
+ params[:controller] %>`
198
+
199
+ When doing this, ensure you are not using the `require_tree` directive, as that
200
+ will result in your assets being included more than once.
201
+
202
+ WARNING: When using asset precompilation, you will need to ensure that your
203
+ controller assets will be precompiled when loading them on a per page basis. By
204
+ default .coffee and .scss files will not be precompiled on their own. See
205
+ [Precompiling Assets](#precompiling-assets) for more information on how
206
+ precompiling works.
207
+
208
+ NOTE: You must have an ExecJS supported runtime in order to use CoffeeScript.
209
+ If you are using Mac OS X or Windows, you have a JavaScript runtime installed in
210
+ your operating system. Check [ExecJS](https://github.com/sstephenson/execjs#readme) documentation to know all supported JavaScript runtimes.
211
+
212
+ You can also disable generation of controller specific asset files by adding the
213
+ following to your `config/application.rb` configuration:
214
+
215
+ ```ruby
216
+ config.generators do |g|
217
+ g.assets false
218
+ end
219
+ ```
220
+
221
+ ### Asset Organization
222
+
223
+ Pipeline assets can be placed inside an application in one of three locations:
224
+ `app/assets`, `lib/assets` or `vendor/assets`.
225
+
226
+ * `app/assets` is for assets that are owned by the application, such as custom
227
+ images, JavaScript files or stylesheets.
228
+
229
+ * `lib/assets` is for your own libraries' code that doesn't really fit into the
230
+ scope of the application or those libraries which are shared across applications.
231
+
232
+ * `vendor/assets` is for assets that are owned by outside entities, such as
233
+ code for JavaScript plugins and CSS frameworks. Keep in mind that third party
234
+ code with references to other files also processed by the asset Pipeline (images,
235
+ stylesheets, etc.), will need to be rewritten to use helpers like `asset_path`.
236
+
237
+ WARNING: If you are upgrading from Rails 3, please take into account that assets
238
+ under `lib/assets` or `vendor/assets` are available for inclusion via the
239
+ application manifests but no longer part of the precompile array. See
240
+ [Precompiling Assets](#precompiling-assets) for guidance.
241
+
242
+ #### Search Paths
243
+
244
+ When a file is referenced from a manifest or a helper, Sprockets searches the
245
+ three default asset locations for it.
246
+
247
+ The default locations are: the `images`, `javascripts` and `stylesheets`
248
+ directories under the `app/assets` folder, but these subdirectories
249
+ are not special - any path under `assets/*` will be searched.
250
+
251
+ For example, these files:
252
+
253
+ ```
254
+ app/assets/javascripts/home.js
255
+ lib/assets/javascripts/moovinator.js
256
+ vendor/assets/javascripts/slider.js
257
+ vendor/assets/somepackage/phonebox.js
258
+ ```
259
+
260
+ would be referenced in a manifest like this:
261
+
262
+ ```js
263
+ //= require home
264
+ //= require moovinator
265
+ //= require slider
266
+ //= require phonebox
267
+ ```
268
+
269
+ Assets inside subdirectories can also be accessed.
270
+
271
+ ```
272
+ app/assets/javascripts/sub/something.js
273
+ ```
274
+
275
+ is referenced as:
276
+
277
+ ```js
278
+ //= require sub/something
279
+ ```
280
+
281
+ You can view the search path by inspecting
282
+ `Rails.application.config.assets.paths` in the Rails console.
283
+
284
+ Besides the standard `assets/*` paths, additional (fully qualified) paths can be
285
+ added to the pipeline in `config/application.rb`. For example:
286
+
287
+ ```ruby
288
+ config.assets.paths << Rails.root.join("lib", "videoplayer", "flash")
289
+ ```
290
+
291
+ Paths are traversed in the order they occur in the search path. By default,
292
+ this means the files in `app/assets` take precedence, and will mask
293
+ corresponding paths in `lib` and `vendor`.
294
+
295
+ It is important to note that files you want to reference outside a manifest must
296
+ be added to the precompile array or they will not be available in the production
297
+ environment.
298
+
299
+ #### Using Index Files
300
+
301
+ Sprockets uses files named `index` (with the relevant extensions) for a special
302
+ purpose.
303
+
304
+ For example, if you have a jQuery library with many modules, which is stored in
305
+ `lib/assets/javascripts/library_name`, the file `lib/assets/javascripts/library_name/index.js` serves as
306
+ the manifest for all files in this library. This file could include a list of
307
+ all the required files in order, or a simple `require_tree` directive.
308
+
309
+ The library as a whole can be accessed in the application manifest like so:
310
+
311
+ ```js
312
+ //= require library_name
313
+ ```
314
+
315
+ This simplifies maintenance and keeps things clean by allowing related code to
316
+ be grouped before inclusion elsewhere.
317
+
318
+ ### Coding Links to Assets
319
+
320
+ Sprockets does not add any new methods to access your assets - you still use the
321
+ familiar `javascript_include_tag` and `stylesheet_link_tag`:
322
+
323
+ ```erb
324
+ <%= stylesheet_link_tag "application", media: "all" %>
325
+ <%= javascript_include_tag "application" %>
326
+ ```
327
+
328
+ If using the turbolinks gem, which is included by default in Rails 4, then
329
+ include the 'data-turbolinks-track' option which causes turbolinks to check if
330
+ an asset has been updated and if so loads it into the page:
331
+
332
+ ```erb
333
+ <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
334
+ <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
335
+ ```
336
+
337
+ In regular views you can access images in the `public/assets/images` directory
338
+ like this:
339
+
340
+ ```erb
341
+ <%= image_tag "rails.png" %>
342
+ ```
343
+
344
+ Provided that the pipeline is enabled within your application (and not disabled
345
+ in the current environment context), this file is served by Sprockets. If a file
346
+ exists at `public/assets/rails.png` it is served by the web server.
347
+
348
+ Alternatively, a request for a file with an MD5 hash such as
349
+ `public/assets/rails-af27b6a414e6da00003503148be9b409.png` is treated the same
350
+ way. How these hashes are generated is covered in the [In
351
+ Production](#in-production) section later on in this guide.
352
+
353
+ Sprockets will also look through the paths specified in `config.assets.paths`,
354
+ which includes the standard application paths and any paths added by Rails
355
+ engines.
356
+
357
+ Images can also be organized into subdirectories if required, and then can be
358
+ accessed by specifying the directory's name in the tag:
359
+
360
+ ```erb
361
+ <%= image_tag "icons/rails.png" %>
362
+ ```
363
+
364
+ WARNING: If you're precompiling your assets (see [In Production](#in-production)
365
+ below), linking to an asset that does not exist will raise an exception in the
366
+ calling page. This includes linking to a blank string. As such, be careful using
367
+ `image_tag` and the other helpers with user-supplied data.
368
+
369
+ #### CSS and ERB
370
+
371
+ The asset pipeline automatically evaluates ERB. This means if you add an
372
+ `erb` extension to a CSS asset (for example, `application.css.erb`), then
373
+ helpers like `asset_path` are available in your CSS rules:
374
+
375
+ ```css
376
+ .class { background-image: url(<%= asset_path 'image.png' %>) }
377
+ ```
378
+
379
+ This writes the path to the particular asset being referenced. In this example,
380
+ it would make sense to have an image in one of the asset load paths, such as
381
+ `app/assets/images/image.png`, which would be referenced here. If this image is
382
+ already available in `public/assets` as a fingerprinted file, then that path is
383
+ referenced.
384
+
385
+ If you want to use a [data URI](http://en.wikipedia.org/wiki/Data_URI_scheme) -
386
+ a method of embedding the image data directly into the CSS file - you can use
387
+ the `asset_data_uri` helper.
388
+
389
+ ```css
390
+ #logo { background: url(<%= asset_data_uri 'logo.png' %>) }
391
+ ```
392
+
393
+ This inserts a correctly-formatted data URI into the CSS source.
394
+
395
+ Note that the closing tag cannot be of the style `-%>`.
396
+
397
+ #### CSS and Sass
398
+
399
+ When using the asset pipeline, paths to assets must be re-written and
400
+ `sass-rails` provides `-url` and `-path` helpers (hyphenated in Sass,
401
+ underscored in Ruby) for the following asset classes: image, font, video, audio,
402
+ JavaScript and stylesheet.
403
+
404
+ * `image-url("rails.png")` becomes `url(/assets/rails.png)`
405
+ * `image-path("rails.png")` becomes `"/assets/rails.png"`.
406
+
407
+ The more generic form can also be used:
408
+
409
+ * `asset-url("rails.png")` becomes `url(/assets/rails.png)`
410
+ * `asset-path("rails.png")` becomes `"/assets/rails.png"`
411
+
412
+ #### JavaScript/CoffeeScript and ERB
413
+
414
+ If you add an `erb` extension to a JavaScript asset, making it something such as
415
+ `application.js.erb`, you can then use the `asset_path` helper in your
416
+ JavaScript code:
417
+
418
+ ```js
419
+ $('#logo').attr({ src: "<%= asset_path('logo.png') %>" });
420
+ ```
421
+
422
+ This writes the path to the particular asset being referenced.
423
+
424
+ Similarly, you can use the `asset_path` helper in CoffeeScript files with `erb`
425
+ extension (e.g., `application.js.coffee.erb`):
426
+
427
+ ```js
428
+ $('#logo').attr src: "<%= asset_path('logo.png') %>"
429
+ ```
430
+
431
+ ### Manifest Files and Directives
432
+
433
+ Sprockets uses manifest files to determine which assets to include and serve.
434
+ These manifest files contain _directives_ - instructions that tell Sprockets
435
+ which files to require in order to build a single CSS or JavaScript file. With
436
+ these directives, Sprockets loads the files specified, processes them if
437
+ necessary, concatenates them into one single file and then compresses them (if
438
+ `Rails.application.config.assets.compress` is true). By serving one file rather
439
+ than many, the load time of pages can be greatly reduced because the browser
440
+ makes fewer requests. Compression also reduces file size, enabling the
441
+ browser to download them faster.
442
+
443
+
444
+ For example, a new Rails 4 application includes a default
445
+ `app/assets/javascripts/application.js` file containing the following lines:
446
+
447
+ ```js
448
+ // ...
449
+ //= require jquery
450
+ //= require jquery_ujs
451
+ //= require_tree .
452
+ ```
453
+
454
+ In JavaScript files, Sprockets directives begin with `//=`. In the above case,
455
+ the file is using the `require` and the `require_tree` directives. The `require`
456
+ directive is used to tell Sprockets the files you wish to require. Here, you are
457
+ requiring the files `jquery.js` and `jquery_ujs.js` that are available somewhere
458
+ in the search path for Sprockets. You need not supply the extensions explicitly.
459
+ Sprockets assumes you are requiring a `.js` file when done from within a `.js`
460
+ file.
461
+
462
+ The `require_tree` directive tells Sprockets to recursively include _all_
463
+ JavaScript files in the specified directory into the output. These paths must be
464
+ specified relative to the manifest file. You can also use the
465
+ `require_directory` directive which includes all JavaScript files only in the
466
+ directory specified, without recursion.
467
+
468
+ Directives are processed top to bottom, but the order in which files are
469
+ included by `require_tree` is unspecified. You should not rely on any particular
470
+ order among those. If you need to ensure some particular JavaScript ends up
471
+ above some other in the concatenated file, require the prerequisite file first
472
+ in the manifest. Note that the family of `require` directives prevents files
473
+ from being included twice in the output.
474
+
475
+ Rails also creates a default `app/assets/stylesheets/application.css` file
476
+ which contains these lines:
477
+
478
+ ```css
479
+ /* ...
480
+ *= require_self
481
+ *= require_tree .
482
+ */
483
+ ```
484
+
485
+ Rails 4 creates both `app/assets/javascripts/application.js` and
486
+ `app/assets/stylesheets/application.css` regardless of whether the
487
+ --skip-sprockets option is used when creating a new rails application. This is
488
+ so you can easily add asset pipelining later if you like.
489
+
490
+ The directives that work in JavaScript files also work in stylesheets
491
+ (though obviously including stylesheets rather than JavaScript files). The
492
+ `require_tree` directive in a CSS manifest works the same way as the JavaScript
493
+ one, requiring all stylesheets from the current directory.
494
+
495
+ In this example, `require_self` is used. This puts the CSS contained within the
496
+ file (if any) at the precise location of the `require_self` call.
497
+
498
+ NOTE. If you want to use multiple Sass files, you should generally use the [Sass `@import` rule](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#import)
499
+ instead of these Sprockets directives. When using Sprockets directives, Sass files exist within
500
+ their own scope, making variables or mixins only available within the document they were defined in.
501
+
502
+ You can do file globbing as well using `@import "*"`, and `@import "**/*"` to add the whole tree which is equivalent to how `require_tree` works. Check the [sass-rails documentation](https://github.com/rails/sass-rails#features) for more info and important caveats.
503
+
504
+ You can have as many manifest files as you need. For example, the `admin.css`
505
+ and `admin.js` manifest could contain the JS and CSS files that are used for the
506
+ admin section of an application.
507
+
508
+ The same remarks about ordering made above apply. In particular, you can specify
509
+ individual files and they are compiled in the order specified. For example, you
510
+ might concatenate three CSS files together this way:
511
+
512
+ ```js
513
+ /* ...
514
+ *= require reset
515
+ *= require layout
516
+ *= require chrome
517
+ */
518
+ ```
519
+
520
+ ### Preprocessing
521
+
522
+ The file extensions used on an asset determine what preprocessing is applied.
523
+ When a controller or a scaffold is generated with the default Rails gemset, a
524
+ CoffeeScript file and a SCSS file are generated in place of a regular JavaScript
525
+ and CSS file. The example used before was a controller called "projects", which
526
+ generated an `app/assets/javascripts/projects.js.coffee` and an
527
+ `app/assets/stylesheets/projects.css.scss` file.
528
+
529
+ In development mode, or if the asset pipeline is disabled, when these files are
530
+ requested they are processed by the processors provided by the `coffee-script`
531
+ and `sass` gems and then sent back to the browser as JavaScript and CSS
532
+ respectively. When asset pipelining is enabled, these files are preprocessed and
533
+ placed in the `public/assets` directory for serving by either the Rails app or
534
+ web server.
535
+
536
+ Additional layers of preprocessing can be requested by adding other extensions,
537
+ where each extension is processed in a right-to-left manner. These should be
538
+ used in the order the processing should be applied. For example, a stylesheet
539
+ called `app/assets/stylesheets/projects.css.scss.erb` is first processed as ERB,
540
+ then SCSS, and finally served as CSS. The same applies to a JavaScript file -
541
+ `app/assets/javascripts/projects.js.coffee.erb` is processed as ERB, then
542
+ CoffeeScript, and served as JavaScript.
543
+
544
+ Keep in mind the order of these preprocessors is important. For example, if
545
+ you called your JavaScript file `app/assets/javascripts/projects.js.erb.coffee`
546
+ then it would be processed with the CoffeeScript interpreter first, which
547
+ wouldn't understand ERB and therefore you would run into problems.
548
+
549
+
550
+ In Development
551
+ --------------
552
+
553
+ In development mode, assets are served as separate files in the order they are
554
+ specified in the manifest file.
555
+
556
+ This manifest `app/assets/javascripts/application.js`:
557
+
558
+ ```js
559
+ //= require core
560
+ //= require projects
561
+ //= require tickets
562
+ ```
563
+
564
+ would generate this HTML:
565
+
566
+ ```html
567
+ <script src="/assets/core.js?body=1"></script>
568
+ <script src="/assets/projects.js?body=1"></script>
569
+ <script src="/assets/tickets.js?body=1"></script>
570
+ ```
571
+
572
+ The `body` param is required by Sprockets.
573
+
574
+ ### Runtime Error Checking
575
+
576
+ By default the asset pipeline will check for potential errors in development mode during
577
+ runtime. To disable this behavior you can set:
578
+
579
+ ```ruby
580
+ config.assets.raise_runtime_errors = false
581
+ ```
582
+
583
+ When this option is true, the asset pipeline will check if all the assets loaded
584
+ in your application are included in the `config.assets.precompile` list.
585
+ If `config.assets.digest` is also true, the asset pipeline will require that
586
+ all requests for assets include digests.
587
+
588
+ ### Turning Digests Off
589
+
590
+ You can turn off digests by updating `config/environments/development.rb` to
591
+ include:
592
+
593
+ ```ruby
594
+ config.assets.digest = false
595
+ ```
596
+
597
+ When this option is true, digests will be generated for asset URLs.
598
+
599
+ ### Turning Debugging Off
600
+
601
+ You can turn off debug mode by updating `config/environments/development.rb` to
602
+ include:
603
+
604
+ ```ruby
605
+ config.assets.debug = false
606
+ ```
607
+
608
+ When debug mode is off, Sprockets concatenates and runs the necessary
609
+ preprocessors on all files. With debug mode turned off the manifest above would
610
+ generate instead:
611
+
612
+ ```html
613
+ <script src="/assets/application.js"></script>
614
+ ```
615
+
616
+ Assets are compiled and cached on the first request after the server is started.
617
+ Sprockets sets a `must-revalidate` Cache-Control HTTP header to reduce request
618
+ overhead on subsequent requests - on these the browser gets a 304 (Not Modified)
619
+ response.
620
+
621
+ If any of the files in the manifest have changed between requests, the server
622
+ responds with a new compiled file.
623
+
624
+ Debug mode can also be enabled in Rails helper methods:
625
+
626
+ ```erb
627
+ <%= stylesheet_link_tag "application", debug: true %>
628
+ <%= javascript_include_tag "application", debug: true %>
629
+ ```
630
+
631
+ The `:debug` option is redundant if debug mode is already on.
632
+
633
+ You can also enable compression in development mode as a sanity check, and
634
+ disable it on-demand as required for debugging.
635
+
636
+ In Production
637
+ -------------
638
+
639
+ In the production environment Sprockets uses the fingerprinting scheme outlined
640
+ above. By default Rails assumes assets have been precompiled and will be
641
+ served as static assets by your web server.
642
+
643
+ During the precompilation phase an MD5 is generated from the contents of the
644
+ compiled files, and inserted into the filenames as they are written to disc.
645
+ These fingerprinted names are used by the Rails helpers in place of the manifest
646
+ name.
647
+
648
+ For example this:
649
+
650
+ ```erb
651
+ <%= javascript_include_tag "application" %>
652
+ <%= stylesheet_link_tag "application" %>
653
+ ```
654
+
655
+ generates something like this:
656
+
657
+ ```html
658
+ <script src="/assets/application-908e25f4bf641868d8683022a5b62f54.js"></script>
659
+ <link href="/assets/application-4dd5b109ee3439da54f5bdfd78a80473.css" media="screen"
660
+ rel="stylesheet" />
661
+ ```
662
+
663
+ Note: with the Asset Pipeline the :cache and :concat options aren't used
664
+ anymore, delete these options from the `javascript_include_tag` and
665
+ `stylesheet_link_tag`.
666
+
667
+ The fingerprinting behavior is controlled by the `config.assets.digest`
668
+ initialization option (which defaults to `true` for production and `false` for
669
+ everything else).
670
+
671
+ NOTE: Under normal circumstances the default `config.assets.digest` option
672
+ should not be changed. If there are no digests in the filenames, and far-future
673
+ headers are set, remote clients will never know to refetch the files when their
674
+ content changes.
675
+
676
+ ### Precompiling Assets
677
+
678
+ Rails comes bundled with a rake task to compile the asset manifests and other
679
+ files in the pipeline.
680
+
681
+ Compiled assets are written to the location specified in `config.assets.prefix`.
682
+ By default, this is the `/assets` directory.
683
+
684
+ You can call this task on the server during deployment to create compiled
685
+ versions of your assets directly on the server. See the next section for
686
+ information on compiling locally.
687
+
688
+ The rake task is:
689
+
690
+ ```bash
691
+ $ RAILS_ENV=production bin/rake assets:precompile
692
+ ```
693
+
694
+ Capistrano (v2.15.1 and above) includes a recipe to handle this in deployment.
695
+ Add the following line to `Capfile`:
696
+
697
+ ```ruby
698
+ load 'deploy/assets'
699
+ ```
700
+
701
+ This links the folder specified in `config.assets.prefix` to `shared/assets`.
702
+ If you already use this shared folder you'll need to write your own deployment
703
+ task.
704
+
705
+ It is important that this folder is shared between deployments so that remotely
706
+ cached pages referencing the old compiled assets still work for the life of
707
+ the cached page.
708
+
709
+ The default matcher for compiling files includes `application.js`,
710
+ `application.css` and all non-JS/CSS files (this will include all image assets
711
+ automatically) from `app/assets` folders including your gems:
712
+
713
+ ```ruby
714
+ [ Proc.new { |filename, path| path =~ /app\/assets/ && !%w(.js .css).include?(File.extname(filename)) },
715
+ /application.(css|js)$/ ]
716
+ ```
717
+
718
+ NOTE: The matcher (and other members of the precompile array; see below) is
719
+ applied to final compiled file names. This means anything that compiles to
720
+ JS/CSS is excluded, as well as raw JS/CSS files; for example, `.coffee` and
721
+ `.scss` files are **not** automatically included as they compile to JS/CSS.
722
+
723
+ If you have other manifests or individual stylesheets and JavaScript files to
724
+ include, you can add them to the `precompile` array in `config/initializers/assets.rb`:
725
+
726
+ ```ruby
727
+ Rails.application.config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']
728
+ ```
729
+
730
+ Or, you can opt to precompile all assets with something like this:
731
+
732
+ ```ruby
733
+ # config/initializers/assets.rb
734
+ Rails.application.config.assets.precompile << Proc.new do |path|
735
+ if path =~ /\.(css|js)\z/
736
+ full_path = Rails.application.assets.resolve(path).to_path
737
+ app_assets_path = Rails.root.join('app', 'assets').to_path
738
+ if full_path.starts_with? app_assets_path
739
+ logger.info "including asset: " + full_path
740
+ true
741
+ else
742
+ logger.info "excluding asset: " + full_path
743
+ false
744
+ end
745
+ else
746
+ false
747
+ end
748
+ end
749
+ ```
750
+
751
+ NOTE. Always specify an expected compiled filename that ends with .js or .css,
752
+ even if you want to add Sass or CoffeeScript files to the precompile array.
753
+
754
+ The rake task also generates a `manifest-md5hash.json` that contains a list with
755
+ all your assets and their respective fingerprints. This is used by the Rails
756
+ helper methods to avoid handing the mapping requests back to Sprockets. A
757
+ typical manifest file looks like:
758
+
759
+ ```ruby
760
+ {"files":{"application-723d1be6cc741a3aabb1cec24276d681.js":{"logical_path":"application.js","mtime":"2013-07-26T22:55:03-07:00","size":302506,
761
+ "digest":"723d1be6cc741a3aabb1cec24276d681"},"application-12b3c7dd74d2e9df37e7cbb1efa76a6d.css":{"logical_path":"application.css","mtime":"2013-07-26T22:54:54-07:00","size":1560,
762
+ "digest":"12b3c7dd74d2e9df37e7cbb1efa76a6d"},"application-1c5752789588ac18d7e1a50b1f0fd4c2.css":{"logical_path":"application.css","mtime":"2013-07-26T22:56:17-07:00","size":1591,
763
+ "digest":"1c5752789588ac18d7e1a50b1f0fd4c2"},"favicon-a9c641bf2b81f0476e876f7c5e375969.ico":{"logical_path":"favicon.ico","mtime":"2013-07-26T23:00:10-07:00","size":1406,
764
+ "digest":"a9c641bf2b81f0476e876f7c5e375969"},"my_image-231a680f23887d9dd70710ea5efd3c62.png":{"logical_path":"my_image.png","mtime":"2013-07-26T23:00:27-07:00","size":6646,
765
+ "digest":"231a680f23887d9dd70710ea5efd3c62"}},"assets":{"application.js":
766
+ "application-723d1be6cc741a3aabb1cec24276d681.js","application.css":
767
+ "application-1c5752789588ac18d7e1a50b1f0fd4c2.css",
768
+ "favicon.ico":"favicona9c641bf2b81f0476e876f7c5e375969.ico","my_image.png":
769
+ "my_image-231a680f23887d9dd70710ea5efd3c62.png"}}
770
+ ```
771
+
772
+ The default location for the manifest is the root of the location specified in
773
+ `config.assets.prefix` ('/assets' by default).
774
+
775
+ NOTE: If there are missing precompiled files in production you will get an
776
+ `Sprockets::Helpers::RailsHelper::AssetPaths::AssetNotPrecompiledError`
777
+ exception indicating the name of the missing file(s).
778
+
779
+ #### Far-future Expires Header
780
+
781
+ Precompiled assets exist on the file system and are served directly by your web
782
+ server. They do not have far-future headers by default, so to get the benefit of
783
+ fingerprinting you'll have to update your server configuration to add those
784
+ headers.
785
+
786
+ For Apache:
787
+
788
+ ```apache
789
+ # The Expires* directives requires the Apache module
790
+ # `mod_expires` to be enabled.
791
+ <Location /assets/>
792
+ # Use of ETag is discouraged when Last-Modified is present
793
+ Header unset ETag
794
+ FileETag None
795
+ # RFC says only cache for 1 year
796
+ ExpiresActive On
797
+ ExpiresDefault "access plus 1 year"
798
+ </Location>
799
+ ```
800
+
801
+ For NGINX:
802
+
803
+ ```nginx
804
+ location ~ ^/assets/ {
805
+ expires 1y;
806
+ add_header Cache-Control public;
807
+
808
+ add_header ETag "";
809
+ break;
810
+ }
811
+ ```
812
+
813
+ #### GZip Compression
814
+
815
+ When files are precompiled, Sprockets also creates a
816
+ [gzipped](http://en.wikipedia.org/wiki/Gzip) (.gz) version of your assets. Web
817
+ servers are typically configured to use a moderate compression ratio as a
818
+ compromise, but since precompilation happens once, Sprockets uses the maximum
819
+ compression ratio, thus reducing the size of the data transfer to the minimum.
820
+ On the other hand, web servers can be configured to serve compressed content
821
+ directly from disk, rather than deflating non-compressed files themselves.
822
+
823
+ NGINX is able to do this automatically enabling `gzip_static`:
824
+
825
+ ```nginx
826
+ location ~ ^/(assets)/ {
827
+ root /path/to/public;
828
+ gzip_static on; # to serve pre-gzipped version
829
+ expires max;
830
+ add_header Cache-Control public;
831
+ }
832
+ ```
833
+
834
+ This directive is available if the core module that provides this feature was
835
+ compiled with the web server. Ubuntu/Debian packages, even `nginx-light`, have
836
+ the module compiled. Otherwise, you may need to perform a manual compilation:
837
+
838
+ ```bash
839
+ ./configure --with-http_gzip_static_module
840
+ ```
841
+
842
+ If you're compiling NGINX with Phusion Passenger you'll need to pass that option
843
+ when prompted.
844
+
845
+ A robust configuration for Apache is possible but tricky; please Google around.
846
+ (Or help update this Guide if you have a good configuration example for Apache.)
847
+
848
+ ### Local Precompilation
849
+
850
+ There are several reasons why you might want to precompile your assets locally.
851
+ Among them are:
852
+
853
+ * You may not have write access to your production file system.
854
+ * You may be deploying to more than one server, and want to avoid
855
+ duplication of work.
856
+ * You may be doing frequent deploys that do not include asset changes.
857
+
858
+ Local compilation allows you to commit the compiled files into source control,
859
+ and deploy as normal.
860
+
861
+ There are three caveats:
862
+
863
+ * You must not run the Capistrano deployment task that precompiles assets.
864
+ * You must ensure any necessary compressors or minifiers are
865
+ available on your development system.
866
+ * You must change the following application configuration setting:
867
+
868
+ In `config/environments/development.rb`, place the following line:
869
+
870
+ ```ruby
871
+ config.assets.prefix = "/dev-assets"
872
+ ```
873
+
874
+ The `prefix` change makes Sprockets use a different URL for serving assets in
875
+ development mode, and pass all requests to Sprockets. The prefix is still set to
876
+ `/assets` in the production environment. Without this change, the application
877
+ would serve the precompiled assets from `/assets` in development, and you would
878
+ not see any local changes until you compile assets again.
879
+
880
+ In practice, this will allow you to precompile locally, have those files in your
881
+ working tree, and commit those files to source control when needed. Development
882
+ mode will work as expected.
883
+
884
+ ### Live Compilation
885
+
886
+ In some circumstances you may wish to use live compilation. In this mode all
887
+ requests for assets in the pipeline are handled by Sprockets directly.
888
+
889
+ To enable this option set:
890
+
891
+ ```ruby
892
+ config.assets.compile = true
893
+ ```
894
+
895
+ On the first request the assets are compiled and cached as outlined in
896
+ development above, and the manifest names used in the helpers are altered to
897
+ include the MD5 hash.
898
+
899
+ Sprockets also sets the `Cache-Control` HTTP header to `max-age=31536000`. This
900
+ signals all caches between your server and the client browser that this content
901
+ (the file served) can be cached for 1 year. The effect of this is to reduce the
902
+ number of requests for this asset from your server; the asset has a good chance
903
+ of being in the local browser cache or some intermediate cache.
904
+
905
+ This mode uses more memory, performs more poorly than the default and is not
906
+ recommended.
907
+
908
+ If you are deploying a production application to a system without any
909
+ pre-existing JavaScript runtimes, you may want to add one to your Gemfile:
910
+
911
+ ```ruby
912
+ group :production do
913
+ gem 'therubyracer'
914
+ end
915
+ ```
916
+
917
+ ### CDNs
918
+
919
+ CDN stands for [Content Delivery
920
+ Network](http://en.wikipedia.org/wiki/Content_delivery_network), they are
921
+ primarily designed to cache assets all over the world so that when a browser
922
+ requests the asset, a cached copy will be geographically close to that browser.
923
+ If you are serving assets directly from your Rails server in production, the
924
+ best practice is to use a CDN in front of your application.
925
+
926
+ A common pattern for using a CDN is to set your production application as the
927
+ "origin" server. This means when a browser requests an asset from the CDN and
928
+ there is a cache miss, it will grab the file from your server on the fly and
929
+ then cache it. For example if you are running a Rails application on
930
+ `example.com` and have a CDN configured at `mycdnsubdomain.fictional-cdn.com`,
931
+ then when a request is made to `mycdnsubdomain.fictional-
932
+ cdn.com/assets/smile.png`, the CDN will query your server once at
933
+ `example.com/assets/smile.png` and cache the request. The next request to the
934
+ CDN that comes in to the same URL will hit the cached copy. When the CDN can
935
+ serve an asset directly the request never touches your Rails server. Since the
936
+ assets from a CDN are geographically closer to the browser, the request is
937
+ faster, and since your server doesn't need to spend time serving assets, it can
938
+ focus on serving application code as fast as possible.
939
+
940
+ #### Set up a CDN to Serve Static Assets
941
+
942
+ To set up your CDN you have to have your application running in production on
943
+ the internet at a publically available URL, for example `example.com`. Next
944
+ you'll need to sign up for a CDN service from a cloud hosting provider. When you
945
+ do this you need to configure the "origin" of the CDN to point back at your
946
+ website `example.com`, check your provider for documentation on configuring the
947
+ origin server.
948
+
949
+ The CDN you provisioned should give you a custom subdomain for your application
950
+ such as `mycdnsubdomain.fictional-cdn.com` (note fictional-cdn.com is not a
951
+ valid CDN provider at the time of this writing). Now that you have configured
952
+ your CDN server, you need to tell browsers to use your CDN to grab assets
953
+ instead of your Rails server directly. You can do this by configuring Rails to
954
+ set your CDN as the asset host instead of using a relative path. To set your
955
+ asset host in Rails, you need to set `config.action_controller.asset_host` in
956
+ `config/production.rb`:
957
+
958
+ ```ruby
959
+ config.action_controller.asset_host = 'mycdnsubdomain.fictional-cdn.com'
960
+ ```
961
+
962
+ NOTE: You only need to provide the "host", this is the subdomain and root
963
+ domain, you do not need to specify a protocol or "scheme" such as `http://` or
964
+ `https://`. When a web page is requested, the protocol in the link to your asset
965
+ that is generated will match how the webpage is accessed by default.
966
+
967
+ You can also set this value through an [environment
968
+ variable](http://en.wikipedia.org/wiki/Environment_variable) to make running a
969
+ staging copy of your site easier:
970
+
971
+ ```
972
+ config.action_controller.asset_host = ENV['CDN_HOST']
973
+ ```
974
+
975
+
976
+
977
+ Note: You would need to set `CDN_HOST` on your server to `mycdnsubdomain
978
+ .fictional-cdn.com` for this to work.
979
+
980
+ Once you have configured your server and your CDN when you serve a webpage that
981
+ has an asset:
982
+
983
+ ```erb
984
+ <%= asset_path('smile.png') %>
985
+ ```
986
+
987
+ Instead of returning a path such as `/assets/smile.png` (digests are left out
988
+ for readability). The URL generated will have the full path to your CDN.
989
+
990
+ ```
991
+ http://mycdnsubdomain.fictional-cdn.com/assets/smile.png
992
+ ```
993
+
994
+ If the CDN has a copy of `smile.png` it will serve it to the browser and your
995
+ server doesn't even know it was requested. If the CDN does not have a copy it
996
+ will try to find it a the "origin" `example.com/assets/smile.png` and then store
997
+ it for future use.
998
+
999
+ If you want to serve only some assets from your CDN, you can use custom `:host`
1000
+ option your asset helper, which overwrites value set in
1001
+ `config.action_controller.asset_host`.
1002
+
1003
+ ```erb
1004
+ <%= asset_path 'image.png', host: 'mycdnsubdomain.fictional-cdn.com' %>
1005
+ ```
1006
+
1007
+ #### Customize CDN Caching Behavior
1008
+
1009
+ A CDN works by caching content. If the CDN has stale or bad content, then it is
1010
+ hurting rather than helping your application. The purpose of this section is to
1011
+ describe general caching behavior of most CDNs, your specific provider may
1012
+ behave slightly differently.
1013
+
1014
+ ##### CDN Request Caching
1015
+
1016
+ While a CDN is described as being good for caching assets, in reality caches the
1017
+ entire request. This includes the body of the asset as well as any headers. The
1018
+ most important one being `Cache-Control` which tells the CDN (and web browsers)
1019
+ how to cache contents. This means that if someone requests an asset that does
1020
+ not exist `/assets/i-dont-exist.png` and your Rails application returns a 404,
1021
+ then your CDN will likely cache the 404 page if a valid `Cache-Control` header
1022
+ is present.
1023
+
1024
+ ##### CDN Header Debugging
1025
+
1026
+ One way to check the headers are cached properly in your CDN is by using [curl](
1027
+ http://explainshell.com/explain?cmd=curl+-I+http%3A%2F%2Fwww.example.com). You
1028
+ can request the headers from both your server and your CDN to verify they are
1029
+ the same:
1030
+
1031
+ ```
1032
+ $ curl -I http://www.example/assets/application-
1033
+ d0e099e021c95eb0de3615fd1d8c4d83.css
1034
+ HTTP/1.1 200 OK
1035
+ Server: Cowboy
1036
+ Date: Sun, 24 Aug 2014 20:27:50 GMT
1037
+ Connection: keep-alive
1038
+ Last-Modified: Thu, 08 May 2014 01:24:14 GMT
1039
+ Content-Type: text/css
1040
+ Cache-Control: public, max-age=2592000
1041
+ Content-Length: 126560
1042
+ Via: 1.1 vegur
1043
+ ```
1044
+
1045
+ Versus the CDN copy.
1046
+
1047
+ ```
1048
+ $ curl -I http://mycdnsubdomain.fictional-cdn.com/application-
1049
+ d0e099e021c95eb0de3615fd1d8c4d83.css
1050
+ HTTP/1.1 200 OK Server: Cowboy Last-
1051
+ Modified: Thu, 08 May 2014 01:24:14 GMT Content-Type: text/css
1052
+ Cache-Control:
1053
+ public, max-age=2592000
1054
+ Via: 1.1 vegur
1055
+ Content-Length: 126560
1056
+ Accept-Ranges:
1057
+ bytes
1058
+ Date: Sun, 24 Aug 2014 20:28:45 GMT
1059
+ Via: 1.1 varnish
1060
+ Age: 885814
1061
+ Connection: keep-alive
1062
+ X-Served-By: cache-dfw1828-DFW
1063
+ X-Cache: HIT
1064
+ X-Cache-Hits:
1065
+ 68
1066
+ X-Timer: S1408912125.211638212,VS0,VE0
1067
+ ```
1068
+
1069
+ Check your CDN documentation for any additional information they may provide
1070
+ such as `X-Cache` or for any additional headers they may add.
1071
+
1072
+ ##### CDNs and the Cache-Control Header
1073
+
1074
+ The [cache control
1075
+ header](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) is a W3C
1076
+ specification that describes how a request can be cached. When no CDN is used, a
1077
+ browser will use this information to cache contents. This is very helpful for
1078
+ assets that are not modified so that a browser does not need to re-download a
1079
+ website's CSS or javascript on every request. Generally we want our Rails server
1080
+ to tell our CDN (and browser) that the asset is "public", that means any cache
1081
+ can store the request. Also we commonly want to set `max-age` which is how long
1082
+ the cache will store the object before invalidating the cache. The `max-age`
1083
+ value is set to seconds with a maximum possible value of `31536000` which is one
1084
+ year. You can do this in your rails application by setting
1085
+
1086
+ ```
1087
+ config.static_cache_control = "public, max-age=31536000"
1088
+ ```
1089
+
1090
+ Now when your application serves an asset in production, the CDN will store the
1091
+ asset for up to a year. Since most CDNs also cache headers of the request, this
1092
+ `Cache-Control` will be passed along to all future browsers seeking this asset,
1093
+ the browser then knows that it can store this asset for a very long time before
1094
+ needing to re-request it.
1095
+
1096
+ ##### CDNs and URL based Cache Invalidation
1097
+
1098
+ Most CDNs will cache contents of an asset based on the complete URL. This means
1099
+ that a request to
1100
+
1101
+ ```
1102
+ http://mycdnsubdomain.fictional-cdn.com/assets/smile-123.png
1103
+ ```
1104
+
1105
+ Will be a completely different cache from
1106
+
1107
+ ```
1108
+ http://mycdnsubdomain.fictional-cdn.com/assets/smile.png
1109
+ ```
1110
+
1111
+ If you want to set far future `max-age` in your `Cache-Control` (and you do),
1112
+ then make sure when you change your assets that your cache is invalidated. For
1113
+ example when changing the smiley face in an image from yellow to blue, you want
1114
+ all visitors of your site to get the new blue face. When using a CDN with the
1115
+ Rails asset pipeline `config.assets.digest` is set to true by default so that
1116
+ each asset will have a different file name when it is changed. This way you
1117
+ don't have to ever manually invalidate any items in your cache. By using a
1118
+ different unique asset name instead, your users get the latest asset.
1119
+
1120
+ Customizing the Pipeline
1121
+ ------------------------
1122
+
1123
+ ### CSS Compression
1124
+
1125
+ One of the options for compressing CSS is YUI. The [YUI CSS
1126
+ compressor](http://yui.github.io/yuicompressor/css.html) provides
1127
+ minification.
1128
+
1129
+ The following line enables YUI compression, and requires the `yui-compressor`
1130
+ gem.
1131
+
1132
+ ```ruby
1133
+ config.assets.css_compressor = :yui
1134
+ ```
1135
+ The other option for compressing CSS if you have the sass-rails gem installed is
1136
+
1137
+ ```ruby
1138
+ config.assets.css_compressor = :sass
1139
+ ```
1140
+
1141
+ ### JavaScript Compression
1142
+
1143
+ Possible options for JavaScript compression are `:closure`, `:uglifier` and
1144
+ `:yui`. These require the use of the `closure-compiler`, `uglifier` or
1145
+ `yui-compressor` gems, respectively.
1146
+
1147
+ The default Gemfile includes [uglifier](https://github.com/lautis/uglifier).
1148
+ This gem wraps [UglifyJS](https://github.com/mishoo/UglifyJS) (written for
1149
+ NodeJS) in Ruby. It compresses your code by removing white space and comments,
1150
+ shortening local variable names, and performing other micro-optimizations such
1151
+ as changing `if` and `else` statements to ternary operators where possible.
1152
+
1153
+ The following line invokes `uglifier` for JavaScript compression.
1154
+
1155
+ ```ruby
1156
+ config.assets.js_compressor = :uglifier
1157
+ ```
1158
+
1159
+ NOTE: You will need an [ExecJS](https://github.com/sstephenson/execjs#readme)
1160
+ supported runtime in order to use `uglifier`. If you are using Mac OS X or
1161
+ Windows you have a JavaScript runtime installed in your operating system.
1162
+
1163
+ NOTE: The `config.assets.compress` initialization option is no longer used in
1164
+ Rails 4 to enable either CSS or JavaScript compression. Setting it will have no
1165
+ effect on the application. Instead, setting `config.assets.css_compressor` and
1166
+ `config.assets.js_compressor` will control compression of CSS and JavaScript
1167
+ assets.
1168
+
1169
+ ### Using Your Own Compressor
1170
+
1171
+ The compressor config settings for CSS and JavaScript also take any object.
1172
+ This object must have a `compress` method that takes a string as the sole
1173
+ argument and it must return a string.
1174
+
1175
+ ```ruby
1176
+ class Transformer
1177
+ def compress(string)
1178
+ do_something_returning_a_string(string)
1179
+ end
1180
+ end
1181
+ ```
1182
+
1183
+ To enable this, pass a new object to the config option in `application.rb`:
1184
+
1185
+ ```ruby
1186
+ config.assets.css_compressor = Transformer.new
1187
+ ```
1188
+
1189
+
1190
+ ### Changing the _assets_ Path
1191
+
1192
+ The public path that Sprockets uses by default is `/assets`.
1193
+
1194
+ This can be changed to something else:
1195
+
1196
+ ```ruby
1197
+ config.assets.prefix = "/some_other_path"
1198
+ ```
1199
+
1200
+ This is a handy option if you are updating an older project that didn't use the
1201
+ asset pipeline and already uses this path or you wish to use this path for
1202
+ a new resource.
1203
+
1204
+ ### X-Sendfile Headers
1205
+
1206
+ The X-Sendfile header is a directive to the web server to ignore the response
1207
+ from the application, and instead serve a specified file from disk. This option
1208
+ is off by default, but can be enabled if your server supports it. When enabled,
1209
+ this passes responsibility for serving the file to the web server, which is
1210
+ faster. Have a look at [send_file](http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_file)
1211
+ on how to use this feature.
1212
+
1213
+ Apache and NGINX support this option, which can be enabled in
1214
+ `config/environments/production.rb`:
1215
+
1216
+ ```ruby
1217
+ # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
1218
+ # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
1219
+ ```
1220
+
1221
+ WARNING: If you are upgrading an existing application and intend to use this
1222
+ option, take care to paste this configuration option only into `production.rb`
1223
+ and any other environments you define with production behavior (not
1224
+ `application.rb`).
1225
+
1226
+ TIP: For further details have a look at the docs of your production web server:
1227
+ - [Apache](https://tn123.org/mod_xsendfile/)
1228
+ - [NGINX](http://wiki.nginx.org/XSendfile)
1229
+
1230
+ Assets Cache Store
1231
+ ------------------
1232
+
1233
+ The default Rails cache store will be used by Sprockets to cache assets in
1234
+ development and production. This can be changed by setting
1235
+ `config.assets.cache_store`:
1236
+
1237
+ ```ruby
1238
+ config.assets.cache_store = :memory_store
1239
+ ```
1240
+
1241
+ The options accepted by the assets cache store are the same as the application's
1242
+ cache store.
1243
+
1244
+ ```ruby
1245
+ config.assets.cache_store = :memory_store, { size: 32.megabytes }
1246
+ ```
1247
+
1248
+ To disable the assets cache store:
1249
+
1250
+ ```ruby
1251
+ config.assets.configure do |env|
1252
+ env.cache = ActiveSupport::Cache.lookup_store(:null_store)
1253
+ end
1254
+ ```
1255
+
1256
+ Adding Assets to Your Gems
1257
+ --------------------------
1258
+
1259
+ Assets can also come from external sources in the form of gems.
1260
+
1261
+ A good example of this is the `jquery-rails` gem which comes with Rails as the
1262
+ standard JavaScript library gem. This gem contains an engine class which
1263
+ inherits from `Rails::Engine`. By doing this, Rails is informed that the
1264
+ directory for this gem may contain assets and the `app/assets`, `lib/assets` and
1265
+ `vendor/assets` directories of this engine are added to the search path of
1266
+ Sprockets.
1267
+
1268
+ Making Your Library or Gem a Pre-Processor
1269
+ ------------------------------------------
1270
+
1271
+ As Sprockets uses [Tilt](https://github.com/rtomayko/tilt) as a generic
1272
+ interface to different templating engines, your gem should just implement the
1273
+ Tilt template protocol. Normally, you would subclass `Tilt::Template` and
1274
+ reimplement the `prepare` method, which initializes your template, and the
1275
+ `evaluate` method, which returns the processed source. The original source is
1276
+ stored in `data`. Have a look at
1277
+ [`Tilt::Template`](https://github.com/rtomayko/tilt/blob/master/lib/tilt/template.rb)
1278
+ sources to learn more.
1279
+
1280
+ ```ruby
1281
+ module BangBang
1282
+ class Template < ::Tilt::Template
1283
+ def prepare
1284
+ # Do any initialization here
1285
+ end
1286
+
1287
+ # Adds a "!" to original template.
1288
+ def evaluate(scope, locals, &block)
1289
+ "#{data}!"
1290
+ end
1291
+ end
1292
+ end
1293
+ ```
1294
+
1295
+ Now that you have a `Template` class, it's time to associate it with an
1296
+ extension for template files:
1297
+
1298
+ ```ruby
1299
+ Sprockets.register_engine '.bang', BangBang::Template
1300
+ ```
1301
+
1302
+ Upgrading from Old Versions of Rails
1303
+ ------------------------------------
1304
+
1305
+ There are a few issues when upgrading from Rails 3.0 or Rails 2.x. The first is
1306
+ moving the files from `public/` to the new locations. See [Asset
1307
+ Organization](#asset-organization) above for guidance on the correct locations
1308
+ for different file types.
1309
+
1310
+ Next will be avoiding duplicate JavaScript files. Since jQuery is the default
1311
+ JavaScript library from Rails 3.1 onwards, you don't need to copy `jquery.js`
1312
+ into `app/assets` and it will be included automatically.
1313
+
1314
+ The third is updating the various environment files with the correct default
1315
+ options.
1316
+
1317
+ In `application.rb`:
1318
+
1319
+ ```ruby
1320
+ # Version of your assets, change this if you want to expire all your assets
1321
+ config.assets.version = '1.0'
1322
+
1323
+ # Change the path that assets are served from config.assets.prefix = "/assets"
1324
+ ```
1325
+
1326
+ In `development.rb`:
1327
+
1328
+ ```ruby
1329
+ # Expands the lines which load the assets
1330
+ config.assets.debug = true
1331
+ ```
1332
+
1333
+ And in `production.rb`:
1334
+
1335
+ ```ruby
1336
+ # Choose the compressors to use (if any) config.assets.js_compressor =
1337
+ # :uglifier config.assets.css_compressor = :yui
1338
+
1339
+ # Don't fallback to assets pipeline if a precompiled asset is missed
1340
+ config.assets.compile = false
1341
+
1342
+ # Generate digests for assets URLs. This is planned for deprecation.
1343
+ config.assets.digest = true
1344
+
1345
+ # Precompile additional assets (application.js, application.css, and all
1346
+ # non-JS/CSS are already added) config.assets.precompile += %w( search.js )
1347
+ ```
1348
+
1349
+ Rails 4 no longer sets default config values for Sprockets in `test.rb`, so
1350
+ `test.rb` now requires Sprockets configuration. The old defaults in the test
1351
+ environment are: `config.assets.compile = true`, `config.assets.compress = false`,
1352
+ `config.assets.debug = false` and `config.assets.digest = false`.
1353
+
1354
+ The following should also be added to `Gemfile`:
1355
+
1356
+ ```ruby
1357
+ gem 'sass-rails', "~> 3.2.3"
1358
+ gem 'coffee-rails', "~> 3.2.1"
1359
+ gem 'uglifier'
1360
+ ```