rails 4.1.4 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -10
  3. data/guides/CHANGELOG.md +15 -25
  4. data/guides/Rakefile +5 -3
  5. data/guides/assets/javascripts/guides.js +6 -0
  6. data/guides/assets/stylesheets/main.css +4 -1
  7. data/guides/bug_report_templates/action_controller_gem.rb +2 -2
  8. data/guides/bug_report_templates/action_controller_master.rb +3 -2
  9. data/guides/rails_guides/helpers.rb +1 -1
  10. data/guides/rails_guides/levenshtein.rb +29 -21
  11. data/guides/rails_guides/markdown/renderer.rb +1 -1
  12. data/guides/rails_guides/markdown.rb +11 -7
  13. data/guides/rails_guides.rb +2 -2
  14. data/guides/source/2_2_release_notes.md +1 -1
  15. data/guides/source/2_3_release_notes.md +4 -4
  16. data/guides/source/3_0_release_notes.md +8 -8
  17. data/guides/source/3_1_release_notes.md +5 -2
  18. data/guides/source/3_2_release_notes.md +6 -3
  19. data/guides/source/4_0_release_notes.md +6 -3
  20. data/guides/source/4_1_release_notes.md +10 -11
  21. data/guides/source/4_2_release_notes.md +850 -0
  22. data/guides/source/_license.html.erb +1 -1
  23. data/guides/source/_welcome.html.erb +2 -8
  24. data/guides/source/action_controller_overview.md +84 -10
  25. data/guides/source/action_mailer_basics.md +91 -28
  26. data/guides/source/action_view_overview.md +140 -130
  27. data/guides/source/active_job_basics.md +318 -0
  28. data/guides/source/active_model_basics.md +371 -17
  29. data/guides/source/active_record_basics.md +19 -18
  30. data/guides/source/active_record_callbacks.md +12 -9
  31. data/guides/source/{migrations.md → active_record_migrations.md} +135 -226
  32. data/guides/source/active_record_postgresql.md +433 -0
  33. data/guides/source/active_record_querying.md +269 -259
  34. data/guides/source/active_record_validations.md +21 -12
  35. data/guides/source/active_support_core_extensions.md +113 -73
  36. data/guides/source/active_support_instrumentation.md +10 -7
  37. data/guides/source/api_documentation_guidelines.md +62 -16
  38. data/guides/source/asset_pipeline.md +264 -67
  39. data/guides/source/association_basics.md +81 -74
  40. data/guides/source/caching_with_rails.md +32 -7
  41. data/guides/source/command_line.md +52 -30
  42. data/guides/source/configuring.md +132 -29
  43. data/guides/source/constant_autoloading_and_reloading.md +1297 -0
  44. data/guides/source/contributing_to_ruby_on_rails.md +192 -112
  45. data/guides/source/credits.html.erb +2 -2
  46. data/guides/source/debugging_rails_applications.md +448 -294
  47. data/guides/source/development_dependencies_install.md +47 -36
  48. data/guides/source/documents.yaml +19 -7
  49. data/guides/source/engines.md +210 -189
  50. data/guides/source/form_helpers.md +79 -56
  51. data/guides/source/generators.md +24 -11
  52. data/guides/source/getting_started.md +339 -201
  53. data/guides/source/i18n.md +111 -68
  54. data/guides/source/index.html.erb +1 -0
  55. data/guides/source/initialization.md +109 -62
  56. data/guides/source/layout.html.erb +1 -4
  57. data/guides/source/layouts_and_rendering.md +18 -17
  58. data/guides/source/maintenance_policy.md +26 -4
  59. data/guides/source/nested_model_forms.md +7 -4
  60. data/guides/source/plugins.md +27 -27
  61. data/guides/source/rails_application_templates.md +21 -3
  62. data/guides/source/rails_on_rack.md +12 -9
  63. data/guides/source/routing.md +100 -74
  64. data/guides/source/ruby_on_rails_guides_guidelines.md +11 -12
  65. data/guides/source/security.md +40 -34
  66. data/guides/source/testing.md +188 -117
  67. data/guides/source/upgrading_ruby_on_rails.md +284 -29
  68. data/guides/source/working_with_javascript_in_rails.md +18 -16
  69. data/guides/w3c_validator.rb +2 -0
  70. metadata +40 -94
  71. data/guides/code/getting_started/Gemfile +0 -40
  72. data/guides/code/getting_started/Gemfile.lock +0 -125
  73. data/guides/code/getting_started/README.rdoc +0 -28
  74. data/guides/code/getting_started/Rakefile +0 -6
  75. data/guides/code/getting_started/app/assets/javascripts/application.js +0 -15
  76. data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +0 -3
  77. data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +0 -3
  78. data/guides/code/getting_started/app/assets/javascripts/welcome.js.coffee +0 -3
  79. data/guides/code/getting_started/app/assets/stylesheets/application.css +0 -13
  80. data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +0 -3
  81. data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +0 -3
  82. data/guides/code/getting_started/app/assets/stylesheets/welcome.css.scss +0 -3
  83. data/guides/code/getting_started/app/controllers/application_controller.rb +0 -5
  84. data/guides/code/getting_started/app/controllers/comments_controller.rb +0 -23
  85. data/guides/code/getting_started/app/controllers/posts_controller.rb +0 -53
  86. data/guides/code/getting_started/app/controllers/welcome_controller.rb +0 -4
  87. data/guides/code/getting_started/app/helpers/application_helper.rb +0 -2
  88. data/guides/code/getting_started/app/helpers/comments_helper.rb +0 -2
  89. data/guides/code/getting_started/app/helpers/posts_helper.rb +0 -2
  90. data/guides/code/getting_started/app/helpers/welcome_helper.rb +0 -2
  91. data/guides/code/getting_started/app/models/comment.rb +0 -3
  92. data/guides/code/getting_started/app/models/post.rb +0 -7
  93. data/guides/code/getting_started/app/views/comments/_comment.html.erb +0 -15
  94. data/guides/code/getting_started/app/views/comments/_form.html.erb +0 -13
  95. data/guides/code/getting_started/app/views/layouts/application.html.erb +0 -14
  96. data/guides/code/getting_started/app/views/posts/_form.html.erb +0 -27
  97. data/guides/code/getting_started/app/views/posts/edit.html.erb +0 -5
  98. data/guides/code/getting_started/app/views/posts/index.html.erb +0 -21
  99. data/guides/code/getting_started/app/views/posts/new.html.erb +0 -5
  100. data/guides/code/getting_started/app/views/posts/show.html.erb +0 -18
  101. data/guides/code/getting_started/app/views/welcome/index.html.erb +0 -4
  102. data/guides/code/getting_started/bin/bundle +0 -4
  103. data/guides/code/getting_started/bin/rails +0 -4
  104. data/guides/code/getting_started/bin/rake +0 -4
  105. data/guides/code/getting_started/config/application.rb +0 -18
  106. data/guides/code/getting_started/config/boot.rb +0 -4
  107. data/guides/code/getting_started/config/database.yml +0 -25
  108. data/guides/code/getting_started/config/environment.rb +0 -5
  109. data/guides/code/getting_started/config/environments/development.rb +0 -30
  110. data/guides/code/getting_started/config/environments/production.rb +0 -80
  111. data/guides/code/getting_started/config/environments/test.rb +0 -36
  112. data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +0 -7
  113. data/guides/code/getting_started/config/initializers/filter_parameter_logging.rb +0 -4
  114. data/guides/code/getting_started/config/initializers/inflections.rb +0 -16
  115. data/guides/code/getting_started/config/initializers/locale.rb +0 -9
  116. data/guides/code/getting_started/config/initializers/mime_types.rb +0 -5
  117. data/guides/code/getting_started/config/initializers/secret_token.rb +0 -12
  118. data/guides/code/getting_started/config/initializers/session_store.rb +0 -3
  119. data/guides/code/getting_started/config/initializers/wrap_parameters.rb +0 -14
  120. data/guides/code/getting_started/config/locales/en.yml +0 -23
  121. data/guides/code/getting_started/config/routes.rb +0 -7
  122. data/guides/code/getting_started/config.ru +0 -4
  123. data/guides/code/getting_started/db/migrate/20130122042648_create_posts.rb +0 -10
  124. data/guides/code/getting_started/db/migrate/20130122045842_create_comments.rb +0 -11
  125. data/guides/code/getting_started/db/schema.rb +0 -33
  126. data/guides/code/getting_started/db/seeds.rb +0 -7
  127. data/guides/code/getting_started/public/404.html +0 -60
  128. data/guides/code/getting_started/public/422.html +0 -60
  129. data/guides/code/getting_started/public/500.html +0 -59
  130. data/guides/code/getting_started/public/favicon.ico +0 -0
  131. data/guides/code/getting_started/public/robots.txt +0 -5
  132. data/guides/code/getting_started/test/controllers/comments_controller_test.rb +0 -7
  133. data/guides/code/getting_started/test/controllers/posts_controller_test.rb +0 -7
  134. data/guides/code/getting_started/test/controllers/welcome_controller_test.rb +0 -9
  135. data/guides/code/getting_started/test/fixtures/comments.yml +0 -11
  136. data/guides/code/getting_started/test/fixtures/posts.yml +0 -9
  137. data/guides/code/getting_started/test/helpers/comments_helper_test.rb +0 -4
  138. data/guides/code/getting_started/test/helpers/posts_helper_test.rb +0 -4
  139. data/guides/code/getting_started/test/helpers/welcome_helper_test.rb +0 -4
  140. data/guides/code/getting_started/test/models/comment_test.rb +0 -7
  141. data/guides/code/getting_started/test/models/post_test.rb +0 -7
  142. data/guides/code/getting_started/test/test_helper.rb +0 -12
@@ -56,11 +56,11 @@ the comment operator on that line to later enable the asset pipeline:
56
56
 
57
57
  To set asset compression methods, set the appropriate configuration options
58
58
  in `production.rb` - `config.assets.css_compressor` for your CSS and
59
- `config.assets.js_compressor` for your Javascript:
59
+ `config.assets.js_compressor` for your JavaScript:
60
60
 
61
61
  ```ruby
62
62
  config.assets.css_compressor = :yui
63
- config.assets.js_compressor = :uglify
63
+ config.assets.js_compressor = :uglifier
64
64
  ```
65
65
 
66
66
  NOTE: The `sass-rails` gem is automatically used for CSS compression if included
@@ -124,19 +124,22 @@ with a built-in helper. In the source the generated code looked like this:
124
124
  The query string strategy has several disadvantages:
125
125
 
126
126
  1. **Not all caches will reliably cache content where the filename only differs by
127
- query parameters**<br>
127
+ query parameters**
128
+
128
129
  [Steve Souders recommends](http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/),
129
130
  "...avoiding a querystring for cacheable resources". He found that in this
130
131
  case 5-20% of requests will not be cached. Query strings in particular do not
131
132
  work at all with some CDNs for cache invalidation.
132
133
 
133
- 2. **The file name can change between nodes in multi-server environments.**<br>
134
+ 2. **The file name can change between nodes in multi-server environments.**
135
+
134
136
  The default query string in Rails 2.x is based on the modification time of
135
137
  the files. When assets are deployed to a cluster, there is no guarantee that the
136
138
  timestamps will be the same, resulting in different values being used depending
137
139
  on which server handles the request.
138
140
 
139
- 3. **Too much cache invalidation**<br>
141
+ 3. **Too much cache invalidation**
142
+
140
143
  When static assets are deployed with each new release of code, the mtime
141
144
  (time of last modification) of _all_ these files changes, forcing all remote
142
145
  clients to fetch them again, even when the content of those assets has not changed.
@@ -163,9 +166,9 @@ pipeline, the preferred location for these assets is now the `app/assets`
163
166
  directory. Files in this directory are served by the Sprockets middleware.
164
167
 
165
168
  Assets can still be placed in the `public` hierarchy. Any assets under `public`
166
- will be served as static files by the application or web server. You should use
167
- `app/assets` for files that must undergo some pre-processing before they are
168
- served.
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.
169
172
 
170
173
  In production, Rails precompiles these files to `public/assets` by default. The
171
174
  precompiled copies are then served as static assets by the web server. The files
@@ -198,18 +201,13 @@ will result in your assets being included more than once.
198
201
 
199
202
  WARNING: When using asset precompilation, you will need to ensure that your
200
203
  controller assets will be precompiled when loading them on a per page basis. By
201
- default .coffee and .scss files will not be precompiled on their own. This will
202
- result in false positives during development as these files will work just fine
203
- since assets are compiled on the fly in development mode. When running in
204
- production, however, you will see 500 errors since live compilation is turned
205
- off by default. See [Precompiling Assets](#precompiling-assets) for more
206
- information on how precompiling works.
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
207
 
208
208
  NOTE: You must have an ExecJS supported runtime in order to use CoffeeScript.
209
209
  If you are using Mac OS X or Windows, you have a JavaScript runtime installed in
210
- your operating system. Check
211
- [ExecJS](https://github.com/sstephenson/execjs#readme) documentation to know all
212
- supported JavaScript runtimes.
210
+ your operating system. Check [ExecJS](https://github.com/sstephenson/execjs#readme) documentation to know all supported JavaScript runtimes.
213
211
 
214
212
  You can also disable generation of controller specific asset files by adding the
215
213
  following to your `config/application.rb` configuration:
@@ -232,7 +230,9 @@ images, JavaScript files or stylesheets.
232
230
  scope of the application or those libraries which are shared across applications.
233
231
 
234
232
  * `vendor/assets` is for assets that are owned by outside entities, such as
235
- code for JavaScript plugins and CSS frameworks.
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
236
 
237
237
  WARNING: If you are upgrading from Rails 3, please take into account that assets
238
238
  under `lib/assets` or `vendor/assets` are available for inclusion via the
@@ -302,7 +302,7 @@ Sprockets uses files named `index` (with the relevant extensions) for a special
302
302
  purpose.
303
303
 
304
304
  For example, if you have a jQuery library with many modules, which is stored in
305
- `lib/assets/library_name`, the file `lib/assets/library_name/index.js` serves as
305
+ `lib/assets/javascripts/library_name`, the file `lib/assets/javascripts/library_name/index.js` serves as
306
306
  the manifest for all files in this library. This file could include a list of
307
307
  all the required files in order, or a simple `require_tree` directive.
308
308
 
@@ -493,14 +493,13 @@ The directives that work in JavaScript files also work in stylesheets
493
493
  one, requiring all stylesheets from the current directory.
494
494
 
495
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. If
497
- `require_self` is called more than once, only the last call is respected.
496
+ file (if any) at the precise location of the `require_self` call.
498
497
 
499
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)
500
- instead of these Sprockets directives. Using Sprockets directives all Sass files exist within
499
+ instead of these Sprockets directives. When using Sprockets directives, Sass files exist within
501
500
  their own scope, making variables or mixins only available within the document they were defined in.
502
- You can do file globbing as well using `@import "*"`, and `@import "**/*"` to add the whole tree
503
- equivalent to how `require_tree` works. Check the [sass-rails documentation](https://github.com/rails/sass-rails#features) for more info and important caveats.
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.
504
503
 
505
504
  You can have as many manifest files as you need. For example, the `admin.css`
506
505
  and `admin.js` manifest could contain the JS and CSS files that are used for the
@@ -581,23 +580,21 @@ runtime. To disable this behavior you can set:
581
580
  config.assets.raise_runtime_errors = false
582
581
  ```
583
582
 
584
- When `raise_runtime_errors` is set to `false` sprockets will not check that dependencies of assets are declared properly. Here is a scenario where you must tell the asset pipeline about a dependency:
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.
585
587
 
586
- If you have `application.css.erb` that references `logo.png` like this:
588
+ ### Turning Digests Off
587
589
 
588
- ```css
589
- #logo { background: url(<%= asset_data_uri 'logo.png' %>) }
590
- ```
591
-
592
- Then you must declare that `logo.png` is a dependency of `application.css.erb`, so when the image gets re-compiled, the css file does as well. You can do this using the `//= depend_on_asset` declaration:
590
+ You can turn off digests by updating `config/environments/development.rb` to
591
+ include:
593
592
 
594
- ```css
595
- //= depend_on_asset "logo.png"
596
- #logo { background: url(<%= asset_data_uri 'logo.png' %>) }
593
+ ```ruby
594
+ config.assets.digest = false
597
595
  ```
598
596
 
599
- Without this declaration you may experience strange behavior when pushing to production that is difficult to debug. When you have `raise_runtime_errors` set to `true`, dependencies will be checked at runtime so you can ensure that all dependencies are met.
600
-
597
+ When this option is true, digests will be generated for asset URLs.
601
598
 
602
599
  ### Turning Debugging Off
603
600
 
@@ -714,7 +711,7 @@ The default matcher for compiling files includes `application.js`,
714
711
  automatically) from `app/assets` folders including your gems:
715
712
 
716
713
  ```ruby
717
- [ Proc.new { |path, fn| fn =~ /app\/assets/ && !%w(.js .css).include?(File.extname(path)) },
714
+ [ Proc.new { |filename, path| path =~ /app\/assets/ && !%w(.js .css).include?(File.extname(filename)) },
718
715
  /application.(css|js)$/ ]
719
716
  ```
720
717
 
@@ -739,10 +736,10 @@ Rails.application.config.assets.precompile << Proc.new do |path|
739
736
  full_path = Rails.application.assets.resolve(path).to_path
740
737
  app_assets_path = Rails.root.join('app', 'assets').to_path
741
738
  if full_path.starts_with? app_assets_path
742
- puts "including asset: " + full_path
739
+ logger.info "including asset: " + full_path
743
740
  true
744
741
  else
745
- puts "excluding asset: " + full_path
742
+ logger.info "excluding asset: " + full_path
746
743
  false
747
744
  end
748
745
  else
@@ -765,7 +762,7 @@ typical manifest file looks like:
765
762
  "digest":"12b3c7dd74d2e9df37e7cbb1efa76a6d"},"application-1c5752789588ac18d7e1a50b1f0fd4c2.css":{"logical_path":"application.css","mtime":"2013-07-26T22:56:17-07:00","size":1591,
766
763
  "digest":"1c5752789588ac18d7e1a50b1f0fd4c2"},"favicon-a9c641bf2b81f0476e876f7c5e375969.ico":{"logical_path":"favicon.ico","mtime":"2013-07-26T23:00:10-07:00","size":1406,
767
764
  "digest":"a9c641bf2b81f0476e876f7c5e375969"},"my_image-231a680f23887d9dd70710ea5efd3c62.png":{"logical_path":"my_image.png","mtime":"2013-07-26T23:00:27-07:00","size":6646,
768
- "digest":"231a680f23887d9dd70710ea5efd3c62"}},"assets"{"application.js":
765
+ "digest":"231a680f23887d9dd70710ea5efd3c62"}},"assets":{"application.js":
769
766
  "application-723d1be6cc741a3aabb1cec24276d681.js","application.css":
770
767
  "application-1c5752789588ac18d7e1a50b1f0fd4c2.css",
771
768
  "favicon.ico":"favicona9c641bf2b81f0476e876f7c5e375969.ico","my_image.png":
@@ -781,7 +778,7 @@ exception indicating the name of the missing file(s).
781
778
 
782
779
  #### Far-future Expires Header
783
780
 
784
- Precompiled assets exist on the filesystem and are served directly by your web
781
+ Precompiled assets exist on the file system and are served directly by your web
785
782
  server. They do not have far-future headers by default, so to get the benefit of
786
783
  fingerprinting you'll have to update your server configuration to add those
787
784
  headers.
@@ -793,13 +790,15 @@ For Apache:
793
790
  # `mod_expires` to be enabled.
794
791
  <Location /assets/>
795
792
  # Use of ETag is discouraged when Last-Modified is present
796
- Header unset ETag FileETag None
793
+ Header unset ETag
794
+ FileETag None
797
795
  # RFC says only cache for 1 year
798
- ExpiresActive On ExpiresDefault "access plus 1 year"
796
+ ExpiresActive On
797
+ ExpiresDefault "access plus 1 year"
799
798
  </Location>
800
799
  ```
801
800
 
802
- For nginx:
801
+ For NGINX:
803
802
 
804
803
  ```nginx
805
804
  location ~ ^/assets/ {
@@ -821,7 +820,7 @@ compression ratio, thus reducing the size of the data transfer to the minimum.
821
820
  On the other hand, web servers can be configured to serve compressed content
822
821
  directly from disk, rather than deflating non-compressed files themselves.
823
822
 
824
- Nginx is able to do this automatically enabling `gzip_static`:
823
+ NGINX is able to do this automatically enabling `gzip_static`:
825
824
 
826
825
  ```nginx
827
826
  location ~ ^/(assets)/ {
@@ -840,7 +839,7 @@ the module compiled. Otherwise, you may need to perform a manual compilation:
840
839
  ./configure --with-http_gzip_static_module
841
840
  ```
842
841
 
843
- If you're compiling nginx with Phusion Passenger you'll need to pass that option
842
+ If you're compiling NGINX with Phusion Passenger you'll need to pass that option
844
843
  when prompted.
845
844
 
846
845
  A robust configuration for Apache is possible but tricky; please Google around.
@@ -859,10 +858,12 @@ duplication of work.
859
858
  Local compilation allows you to commit the compiled files into source control,
860
859
  and deploy as normal.
861
860
 
862
- There are two caveats:
861
+ There are three caveats:
863
862
 
864
863
  * You must not run the Capistrano deployment task that precompiles assets.
865
- * You must change the following two application configuration settings.
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:
866
867
 
867
868
  In `config/environments/development.rb`, place the following line:
868
869
 
@@ -876,9 +877,6 @@ development mode, and pass all requests to Sprockets. The prefix is still set to
876
877
  would serve the precompiled assets from `/assets` in development, and you would
877
878
  not see any local changes until you compile assets again.
878
879
 
879
- You will also need to ensure any necessary compressors or minifiers are
880
- available on your development system.
881
-
882
880
  In practice, this will allow you to precompile locally, have those files in your
883
881
  working tree, and commit those files to source control when needed. Development
884
882
  mode will work as expected.
@@ -918,15 +916,206 @@ end
918
916
 
919
917
  ### CDNs
920
918
 
921
- If your assets are being served by a CDN, ensure they don't stick around in your
922
- cache forever. This can cause problems. If you use
923
- `config.action_controller.perform_caching = true`, Rack::Cache will use
924
- `Rails.cache` to store assets. This can cause your cache to fill up quickly.
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
+
925
976
 
926
- Every cache is different, so evaluate how your CDN handles caching and make sure
927
- that it plays nicely with the pipeline. You may find quirks related to your
928
- specific set up, you may not. The defaults nginx uses, for example, should give
929
- you no problems when used as an HTTP cache.
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.
930
1119
 
931
1120
  Customizing the Pipeline
932
1121
  ------------------------
@@ -943,7 +1132,7 @@ gem.
943
1132
  ```ruby
944
1133
  config.assets.css_compressor = :yui
945
1134
  ```
946
- The other option for compressing CSS if you have the sass-rails gem installed is
1135
+ The other option for compressing CSS if you have the sass-rails gem installed is
947
1136
 
948
1137
  ```ruby
949
1138
  config.assets.css_compressor = :sass
@@ -1018,15 +1207,15 @@ The X-Sendfile header is a directive to the web server to ignore the response
1018
1207
  from the application, and instead serve a specified file from disk. This option
1019
1208
  is off by default, but can be enabled if your server supports it. When enabled,
1020
1209
  this passes responsibility for serving the file to the web server, which is
1021
- faster. Have a look at [send_file](http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_file)
1210
+ faster. Have a look at [send_file](http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_file)
1022
1211
  on how to use this feature.
1023
1212
 
1024
- Apache and nginx support this option, which can be enabled in
1213
+ Apache and NGINX support this option, which can be enabled in
1025
1214
  `config/environments/production.rb`:
1026
1215
 
1027
1216
  ```ruby
1028
- # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
1029
- # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
1217
+ # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
1218
+ # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
1030
1219
  ```
1031
1220
 
1032
1221
  WARNING: If you are upgrading an existing application and intend to use this
@@ -1036,7 +1225,7 @@ and any other environments you define with production behavior (not
1036
1225
 
1037
1226
  TIP: For further details have a look at the docs of your production web server:
1038
1227
  - [Apache](https://tn123.org/mod_xsendfile/)
1039
- - [Nginx](http://wiki.nginx.org/XSendfile)
1228
+ - [NGINX](http://wiki.nginx.org/XSendfile)
1040
1229
 
1041
1230
  Assets Cache Store
1042
1231
  ------------------
@@ -1056,6 +1245,14 @@ cache store.
1056
1245
  config.assets.cache_store = :memory_store, { size: 32.megabytes }
1057
1246
  ```
1058
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
+
1059
1256
  Adding Assets to Your Gems
1060
1257
  --------------------------
1061
1258
 
@@ -1151,8 +1348,8 @@ config.assets.digest = true
1151
1348
 
1152
1349
  Rails 4 no longer sets default config values for Sprockets in `test.rb`, so
1153
1350
  `test.rb` now requires Sprockets configuration. The old defaults in the test
1154
- environment are: `config.assets.compile = true`, `config.assets.compress =
1155
- false`, `config.assets.debug = false` and `config.assets.digest = false`.
1351
+ environment are: `config.assets.compile = true`, `config.assets.compress = false`,
1352
+ `config.assets.debug = false` and `config.assets.digest = false`.
1156
1353
 
1157
1354
  The following should also be added to `Gemfile`:
1158
1355