rails 4.1.4 → 4.2.11.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +12 -10
- data/guides/CHANGELOG.md +87 -15
- data/guides/Rakefile +21 -6
- data/guides/assets/images/getting_started/article_with_comments.png +0 -0
- data/guides/assets/javascripts/guides.js +6 -0
- data/guides/assets/stylesheets/main.css +4 -1
- data/guides/bug_report_templates/action_controller_gem.rb +3 -3
- data/guides/bug_report_templates/action_controller_master.rb +3 -2
- data/guides/bug_report_templates/active_record_gem.rb +1 -1
- data/guides/bug_report_templates/generic_gem.rb +15 -0
- data/guides/bug_report_templates/generic_master.rb +26 -0
- data/guides/rails_guides/helpers.rb +1 -1
- data/guides/rails_guides/levenshtein.rb +27 -21
- data/guides/rails_guides/markdown/renderer.rb +1 -1
- data/guides/rails_guides/markdown.rb +11 -7
- data/guides/rails_guides.rb +2 -2
- data/guides/source/2_2_release_notes.md +1 -1
- data/guides/source/2_3_release_notes.md +4 -4
- data/guides/source/3_0_release_notes.md +8 -8
- data/guides/source/3_1_release_notes.md +6 -3
- data/guides/source/3_2_release_notes.md +6 -3
- data/guides/source/4_0_release_notes.md +6 -3
- data/guides/source/4_1_release_notes.md +10 -11
- data/guides/source/4_2_release_notes.md +877 -0
- data/guides/source/_license.html.erb +1 -1
- data/guides/source/_welcome.html.erb +6 -8
- data/guides/source/action_controller_overview.md +28 -11
- data/guides/source/action_mailer_basics.md +97 -29
- data/guides/source/action_view_overview.md +142 -191
- data/guides/source/active_job_basics.md +339 -0
- data/guides/source/active_model_basics.md +371 -17
- data/guides/source/active_record_basics.md +25 -24
- data/guides/source/active_record_callbacks.md +12 -9
- data/guides/source/{migrations.md → active_record_migrations.md} +135 -226
- data/guides/source/active_record_postgresql.md +433 -0
- data/guides/source/active_record_querying.md +270 -262
- data/guides/source/active_record_validations.md +24 -14
- data/guides/source/active_support_core_extensions.md +115 -123
- data/guides/source/active_support_instrumentation.md +10 -18
- data/guides/source/api_documentation_guidelines.md +63 -17
- data/guides/source/asset_pipeline.md +266 -125
- data/guides/source/association_basics.md +96 -80
- data/guides/source/autoloading_and_reloading_constants.md +1311 -0
- data/guides/source/caching_with_rails.md +32 -7
- data/guides/source/command_line.md +52 -30
- data/guides/source/configuring.md +161 -33
- data/guides/source/contributing_to_ruby_on_rails.md +198 -114
- data/guides/source/credits.html.erb +2 -2
- data/guides/source/debugging_rails_applications.md +448 -294
- data/guides/source/development_dependencies_install.md +47 -36
- data/guides/source/documents.yaml +19 -7
- data/guides/source/engines.md +217 -196
- data/guides/source/form_helpers.md +79 -56
- data/guides/source/generators.md +24 -11
- data/guides/source/getting_started.md +361 -222
- data/guides/source/i18n.md +113 -69
- data/guides/source/index.html.erb +1 -0
- data/guides/source/initialization.md +110 -63
- data/guides/source/layout.html.erb +5 -11
- data/guides/source/layouts_and_rendering.md +26 -26
- data/guides/source/maintenance_policy.md +26 -4
- data/guides/source/nested_model_forms.md +7 -4
- data/guides/source/plugins.md +27 -27
- data/guides/source/rails_application_templates.md +21 -3
- data/guides/source/rails_on_rack.md +12 -10
- data/guides/source/routing.md +115 -75
- data/guides/source/ruby_on_rails_guides_guidelines.md +11 -12
- data/guides/source/security.md +41 -35
- data/guides/source/testing.md +199 -119
- data/guides/source/upgrading_ruby_on_rails.md +319 -32
- data/guides/source/working_with_javascript_in_rails.md +19 -17
- data/guides/w3c_validator.rb +2 -0
- metadata +42 -95
- data/guides/code/getting_started/Gemfile +0 -40
- data/guides/code/getting_started/Gemfile.lock +0 -125
- data/guides/code/getting_started/README.rdoc +0 -28
- data/guides/code/getting_started/Rakefile +0 -6
- data/guides/code/getting_started/app/assets/javascripts/application.js +0 -15
- data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/javascripts/welcome.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/application.css +0 -13
- data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/welcome.css.scss +0 -3
- data/guides/code/getting_started/app/controllers/application_controller.rb +0 -5
- data/guides/code/getting_started/app/controllers/comments_controller.rb +0 -23
- data/guides/code/getting_started/app/controllers/posts_controller.rb +0 -53
- data/guides/code/getting_started/app/controllers/welcome_controller.rb +0 -4
- data/guides/code/getting_started/app/helpers/application_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/comments_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/posts_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/welcome_helper.rb +0 -2
- data/guides/code/getting_started/app/models/comment.rb +0 -3
- data/guides/code/getting_started/app/models/post.rb +0 -7
- data/guides/code/getting_started/app/views/comments/_comment.html.erb +0 -15
- data/guides/code/getting_started/app/views/comments/_form.html.erb +0 -13
- data/guides/code/getting_started/app/views/layouts/application.html.erb +0 -14
- data/guides/code/getting_started/app/views/posts/_form.html.erb +0 -27
- data/guides/code/getting_started/app/views/posts/edit.html.erb +0 -5
- data/guides/code/getting_started/app/views/posts/index.html.erb +0 -21
- data/guides/code/getting_started/app/views/posts/new.html.erb +0 -5
- data/guides/code/getting_started/app/views/posts/show.html.erb +0 -18
- data/guides/code/getting_started/app/views/welcome/index.html.erb +0 -4
- data/guides/code/getting_started/bin/bundle +0 -4
- data/guides/code/getting_started/bin/rails +0 -4
- data/guides/code/getting_started/bin/rake +0 -4
- data/guides/code/getting_started/config/application.rb +0 -18
- data/guides/code/getting_started/config/boot.rb +0 -4
- data/guides/code/getting_started/config/database.yml +0 -25
- data/guides/code/getting_started/config/environment.rb +0 -5
- data/guides/code/getting_started/config/environments/development.rb +0 -30
- data/guides/code/getting_started/config/environments/production.rb +0 -80
- data/guides/code/getting_started/config/environments/test.rb +0 -36
- data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +0 -7
- data/guides/code/getting_started/config/initializers/filter_parameter_logging.rb +0 -4
- data/guides/code/getting_started/config/initializers/inflections.rb +0 -16
- data/guides/code/getting_started/config/initializers/locale.rb +0 -9
- data/guides/code/getting_started/config/initializers/mime_types.rb +0 -5
- data/guides/code/getting_started/config/initializers/secret_token.rb +0 -12
- data/guides/code/getting_started/config/initializers/session_store.rb +0 -3
- data/guides/code/getting_started/config/initializers/wrap_parameters.rb +0 -14
- data/guides/code/getting_started/config/locales/en.yml +0 -23
- data/guides/code/getting_started/config/routes.rb +0 -7
- data/guides/code/getting_started/config.ru +0 -4
- data/guides/code/getting_started/db/migrate/20130122042648_create_posts.rb +0 -10
- data/guides/code/getting_started/db/migrate/20130122045842_create_comments.rb +0 -11
- data/guides/code/getting_started/db/schema.rb +0 -33
- data/guides/code/getting_started/db/seeds.rb +0 -7
- data/guides/code/getting_started/public/404.html +0 -60
- data/guides/code/getting_started/public/422.html +0 -60
- data/guides/code/getting_started/public/500.html +0 -59
- data/guides/code/getting_started/public/favicon.ico +0 -0
- data/guides/code/getting_started/public/robots.txt +0 -5
- data/guides/code/getting_started/test/controllers/comments_controller_test.rb +0 -7
- data/guides/code/getting_started/test/controllers/posts_controller_test.rb +0 -7
- data/guides/code/getting_started/test/controllers/welcome_controller_test.rb +0 -9
- data/guides/code/getting_started/test/fixtures/comments.yml +0 -11
- data/guides/code/getting_started/test/fixtures/posts.yml +0 -9
- data/guides/code/getting_started/test/helpers/comments_helper_test.rb +0 -4
- data/guides/code/getting_started/test/helpers/posts_helper_test.rb +0 -4
- data/guides/code/getting_started/test/helpers/welcome_helper_test.rb +0 -4
- data/guides/code/getting_started/test/models/comment_test.rb +0 -7
- data/guides/code/getting_started/test/models/post_test.rb +0 -7
- 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
|
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 = :
|
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
|
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
|
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
|
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
|
167
|
-
`
|
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.
|
202
|
-
|
203
|
-
|
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/rails/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
|
|
@@ -434,11 +434,11 @@ Sprockets uses manifest files to determine which assets to include and serve.
|
|
434
434
|
These manifest files contain _directives_ - instructions that tell Sprockets
|
435
435
|
which files to require in order to build a single CSS or JavaScript file. With
|
436
436
|
these directives, Sprockets loads the files specified, processes them if
|
437
|
-
necessary, concatenates them into one single file and then compresses them
|
438
|
-
`Rails.application.config.assets.
|
439
|
-
than many, the load time of pages can be greatly reduced because
|
440
|
-
makes fewer requests. Compression also reduces file size, enabling
|
441
|
-
browser to download them faster.
|
437
|
+
necessary, concatenates them into one single file and then compresses them
|
438
|
+
(based on value of `Rails.application.config.assets.js_compressor`). By serving
|
439
|
+
one file rather than many, the load time of pages can be greatly reduced because
|
440
|
+
the browser makes fewer requests. Compression also reduces file size, enabling
|
441
|
+
the browser to download them faster.
|
442
442
|
|
443
443
|
|
444
444
|
For example, a new Rails 4 application includes a default
|
@@ -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.
|
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.
|
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
|
-
|
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
|
585
|
-
|
586
|
-
If
|
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
587
|
|
588
|
-
|
589
|
-
#logo { background: url(<%= asset_data_uri 'logo.png' %>) }
|
590
|
-
```
|
588
|
+
### Turning Digests Off
|
591
589
|
|
592
|
-
|
590
|
+
You can turn off digests by updating `config/environments/development.rb` to
|
591
|
+
include:
|
593
592
|
|
594
|
-
```
|
595
|
-
|
596
|
-
#logo { background: url(<%= asset_data_uri 'logo.png' %>) }
|
593
|
+
```ruby
|
594
|
+
config.assets.digest = false
|
597
595
|
```
|
598
596
|
|
599
|
-
|
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 { |
|
714
|
+
[ Proc.new { |filename, path| path =~ /app\/assets/ && !%w(.js .css).include?(File.extname(filename)) },
|
718
715
|
/application.(css|js)$/ ]
|
719
716
|
```
|
720
717
|
|
@@ -730,27 +727,6 @@ include, you can add them to the `precompile` array in `config/initializers/asse
|
|
730
727
|
Rails.application.config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']
|
731
728
|
```
|
732
729
|
|
733
|
-
Or, you can opt to precompile all assets with something like this:
|
734
|
-
|
735
|
-
```ruby
|
736
|
-
# config/initializers/assets.rb
|
737
|
-
Rails.application.config.assets.precompile << Proc.new do |path|
|
738
|
-
if path =~ /\.(css|js)\z/
|
739
|
-
full_path = Rails.application.assets.resolve(path).to_path
|
740
|
-
app_assets_path = Rails.root.join('app', 'assets').to_path
|
741
|
-
if full_path.starts_with? app_assets_path
|
742
|
-
puts "including asset: " + full_path
|
743
|
-
true
|
744
|
-
else
|
745
|
-
puts "excluding asset: " + full_path
|
746
|
-
false
|
747
|
-
end
|
748
|
-
else
|
749
|
-
false
|
750
|
-
end
|
751
|
-
end
|
752
|
-
```
|
753
|
-
|
754
730
|
NOTE. Always specify an expected compiled filename that ends with .js or .css,
|
755
731
|
even if you want to add Sass or CoffeeScript files to the precompile array.
|
756
732
|
|
@@ -765,7 +741,7 @@ typical manifest file looks like:
|
|
765
741
|
"digest":"12b3c7dd74d2e9df37e7cbb1efa76a6d"},"application-1c5752789588ac18d7e1a50b1f0fd4c2.css":{"logical_path":"application.css","mtime":"2013-07-26T22:56:17-07:00","size":1591,
|
766
742
|
"digest":"1c5752789588ac18d7e1a50b1f0fd4c2"},"favicon-a9c641bf2b81f0476e876f7c5e375969.ico":{"logical_path":"favicon.ico","mtime":"2013-07-26T23:00:10-07:00","size":1406,
|
767
743
|
"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":
|
744
|
+
"digest":"231a680f23887d9dd70710ea5efd3c62"}},"assets":{"application.js":
|
769
745
|
"application-723d1be6cc741a3aabb1cec24276d681.js","application.css":
|
770
746
|
"application-1c5752789588ac18d7e1a50b1f0fd4c2.css",
|
771
747
|
"favicon.ico":"favicona9c641bf2b81f0476e876f7c5e375969.ico","my_image.png":
|
@@ -781,7 +757,7 @@ exception indicating the name of the missing file(s).
|
|
781
757
|
|
782
758
|
#### Far-future Expires Header
|
783
759
|
|
784
|
-
Precompiled assets exist on the
|
760
|
+
Precompiled assets exist on the file system and are served directly by your web
|
785
761
|
server. They do not have far-future headers by default, so to get the benefit of
|
786
762
|
fingerprinting you'll have to update your server configuration to add those
|
787
763
|
headers.
|
@@ -793,13 +769,15 @@ For Apache:
|
|
793
769
|
# `mod_expires` to be enabled.
|
794
770
|
<Location /assets/>
|
795
771
|
# Use of ETag is discouraged when Last-Modified is present
|
796
|
-
Header unset ETag
|
772
|
+
Header unset ETag
|
773
|
+
FileETag None
|
797
774
|
# RFC says only cache for 1 year
|
798
|
-
ExpiresActive On
|
775
|
+
ExpiresActive On
|
776
|
+
ExpiresDefault "access plus 1 year"
|
799
777
|
</Location>
|
800
778
|
```
|
801
779
|
|
802
|
-
For
|
780
|
+
For NGINX:
|
803
781
|
|
804
782
|
```nginx
|
805
783
|
location ~ ^/assets/ {
|
@@ -811,41 +789,6 @@ location ~ ^/assets/ {
|
|
811
789
|
}
|
812
790
|
```
|
813
791
|
|
814
|
-
#### GZip Compression
|
815
|
-
|
816
|
-
When files are precompiled, Sprockets also creates a
|
817
|
-
[gzipped](http://en.wikipedia.org/wiki/Gzip) (.gz) version of your assets. Web
|
818
|
-
servers are typically configured to use a moderate compression ratio as a
|
819
|
-
compromise, but since precompilation happens once, Sprockets uses the maximum
|
820
|
-
compression ratio, thus reducing the size of the data transfer to the minimum.
|
821
|
-
On the other hand, web servers can be configured to serve compressed content
|
822
|
-
directly from disk, rather than deflating non-compressed files themselves.
|
823
|
-
|
824
|
-
Nginx is able to do this automatically enabling `gzip_static`:
|
825
|
-
|
826
|
-
```nginx
|
827
|
-
location ~ ^/(assets)/ {
|
828
|
-
root /path/to/public;
|
829
|
-
gzip_static on; # to serve pre-gzipped version
|
830
|
-
expires max;
|
831
|
-
add_header Cache-Control public;
|
832
|
-
}
|
833
|
-
```
|
834
|
-
|
835
|
-
This directive is available if the core module that provides this feature was
|
836
|
-
compiled with the web server. Ubuntu/Debian packages, even `nginx-light`, have
|
837
|
-
the module compiled. Otherwise, you may need to perform a manual compilation:
|
838
|
-
|
839
|
-
```bash
|
840
|
-
./configure --with-http_gzip_static_module
|
841
|
-
```
|
842
|
-
|
843
|
-
If you're compiling nginx with Phusion Passenger you'll need to pass that option
|
844
|
-
when prompted.
|
845
|
-
|
846
|
-
A robust configuration for Apache is possible but tricky; please Google around.
|
847
|
-
(Or help update this Guide if you have a good configuration example for Apache.)
|
848
|
-
|
849
792
|
### Local Precompilation
|
850
793
|
|
851
794
|
There are several reasons why you might want to precompile your assets locally.
|
@@ -859,10 +802,12 @@ duplication of work.
|
|
859
802
|
Local compilation allows you to commit the compiled files into source control,
|
860
803
|
and deploy as normal.
|
861
804
|
|
862
|
-
There are
|
805
|
+
There are three caveats:
|
863
806
|
|
864
807
|
* You must not run the Capistrano deployment task that precompiles assets.
|
865
|
-
* You must
|
808
|
+
* You must ensure any necessary compressors or minifiers are
|
809
|
+
available on your development system.
|
810
|
+
* You must change the following application configuration setting:
|
866
811
|
|
867
812
|
In `config/environments/development.rb`, place the following line:
|
868
813
|
|
@@ -876,9 +821,6 @@ development mode, and pass all requests to Sprockets. The prefix is still set to
|
|
876
821
|
would serve the precompiled assets from `/assets` in development, and you would
|
877
822
|
not see any local changes until you compile assets again.
|
878
823
|
|
879
|
-
You will also need to ensure any necessary compressors or minifiers are
|
880
|
-
available on your development system.
|
881
|
-
|
882
824
|
In practice, this will allow you to precompile locally, have those files in your
|
883
825
|
working tree, and commit those files to source control when needed. Development
|
884
826
|
mode will work as expected.
|
@@ -918,15 +860,206 @@ end
|
|
918
860
|
|
919
861
|
### CDNs
|
920
862
|
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
863
|
+
CDN stands for [Content Delivery
|
864
|
+
Network](http://en.wikipedia.org/wiki/Content_delivery_network), they are
|
865
|
+
primarily designed to cache assets all over the world so that when a browser
|
866
|
+
requests the asset, a cached copy will be geographically close to that browser.
|
867
|
+
If you are serving assets directly from your Rails server in production, the
|
868
|
+
best practice is to use a CDN in front of your application.
|
869
|
+
|
870
|
+
A common pattern for using a CDN is to set your production application as the
|
871
|
+
"origin" server. This means when a browser requests an asset from the CDN and
|
872
|
+
there is a cache miss, it will grab the file from your server on the fly and
|
873
|
+
then cache it. For example if you are running a Rails application on
|
874
|
+
`example.com` and have a CDN configured at `mycdnsubdomain.fictional-cdn.com`,
|
875
|
+
then when a request is made to `mycdnsubdomain.fictional-
|
876
|
+
cdn.com/assets/smile.png`, the CDN will query your server once at
|
877
|
+
`example.com/assets/smile.png` and cache the request. The next request to the
|
878
|
+
CDN that comes in to the same URL will hit the cached copy. When the CDN can
|
879
|
+
serve an asset directly the request never touches your Rails server. Since the
|
880
|
+
assets from a CDN are geographically closer to the browser, the request is
|
881
|
+
faster, and since your server doesn't need to spend time serving assets, it can
|
882
|
+
focus on serving application code as fast as possible.
|
883
|
+
|
884
|
+
#### Set up a CDN to Serve Static Assets
|
885
|
+
|
886
|
+
To set up your CDN you have to have your application running in production on
|
887
|
+
the internet at a publically available URL, for example `example.com`. Next
|
888
|
+
you'll need to sign up for a CDN service from a cloud hosting provider. When you
|
889
|
+
do this you need to configure the "origin" of the CDN to point back at your
|
890
|
+
website `example.com`, check your provider for documentation on configuring the
|
891
|
+
origin server.
|
892
|
+
|
893
|
+
The CDN you provisioned should give you a custom subdomain for your application
|
894
|
+
such as `mycdnsubdomain.fictional-cdn.com` (note fictional-cdn.com is not a
|
895
|
+
valid CDN provider at the time of this writing). Now that you have configured
|
896
|
+
your CDN server, you need to tell browsers to use your CDN to grab assets
|
897
|
+
instead of your Rails server directly. You can do this by configuring Rails to
|
898
|
+
set your CDN as the asset host instead of using a relative path. To set your
|
899
|
+
asset host in Rails, you need to set `config.action_controller.asset_host` in
|
900
|
+
`config/production.rb`:
|
901
|
+
|
902
|
+
```ruby
|
903
|
+
config.action_controller.asset_host = 'mycdnsubdomain.fictional-cdn.com'
|
904
|
+
```
|
905
|
+
|
906
|
+
NOTE: You only need to provide the "host", this is the subdomain and root
|
907
|
+
domain, you do not need to specify a protocol or "scheme" such as `http://` or
|
908
|
+
`https://`. When a web page is requested, the protocol in the link to your asset
|
909
|
+
that is generated will match how the webpage is accessed by default.
|
910
|
+
|
911
|
+
You can also set this value through an [environment
|
912
|
+
variable](http://en.wikipedia.org/wiki/Environment_variable) to make running a
|
913
|
+
staging copy of your site easier:
|
914
|
+
|
915
|
+
```
|
916
|
+
config.action_controller.asset_host = ENV['CDN_HOST']
|
917
|
+
```
|
918
|
+
|
919
|
+
|
925
920
|
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
you
|
921
|
+
Note: You would need to set `CDN_HOST` on your server to `mycdnsubdomain
|
922
|
+
.fictional-cdn.com` for this to work.
|
923
|
+
|
924
|
+
Once you have configured your server and your CDN when you serve a webpage that
|
925
|
+
has an asset:
|
926
|
+
|
927
|
+
```erb
|
928
|
+
<%= asset_path('smile.png') %>
|
929
|
+
```
|
930
|
+
|
931
|
+
Instead of returning a path such as `/assets/smile.png` (digests are left out
|
932
|
+
for readability). The URL generated will have the full path to your CDN.
|
933
|
+
|
934
|
+
```
|
935
|
+
http://mycdnsubdomain.fictional-cdn.com/assets/smile.png
|
936
|
+
```
|
937
|
+
|
938
|
+
If the CDN has a copy of `smile.png` it will serve it to the browser and your
|
939
|
+
server doesn't even know it was requested. If the CDN does not have a copy it
|
940
|
+
will try to find it a the "origin" `example.com/assets/smile.png` and then store
|
941
|
+
it for future use.
|
942
|
+
|
943
|
+
If you want to serve only some assets from your CDN, you can use custom `:host`
|
944
|
+
option your asset helper, which overwrites value set in
|
945
|
+
`config.action_controller.asset_host`.
|
946
|
+
|
947
|
+
```erb
|
948
|
+
<%= asset_path 'image.png', host: 'mycdnsubdomain.fictional-cdn.com' %>
|
949
|
+
```
|
950
|
+
|
951
|
+
#### Customize CDN Caching Behavior
|
952
|
+
|
953
|
+
A CDN works by caching content. If the CDN has stale or bad content, then it is
|
954
|
+
hurting rather than helping your application. The purpose of this section is to
|
955
|
+
describe general caching behavior of most CDNs, your specific provider may
|
956
|
+
behave slightly differently.
|
957
|
+
|
958
|
+
##### CDN Request Caching
|
959
|
+
|
960
|
+
While a CDN is described as being good for caching assets, in reality caches the
|
961
|
+
entire request. This includes the body of the asset as well as any headers. The
|
962
|
+
most important one being `Cache-Control` which tells the CDN (and web browsers)
|
963
|
+
how to cache contents. This means that if someone requests an asset that does
|
964
|
+
not exist `/assets/i-dont-exist.png` and your Rails application returns a 404,
|
965
|
+
then your CDN will likely cache the 404 page if a valid `Cache-Control` header
|
966
|
+
is present.
|
967
|
+
|
968
|
+
##### CDN Header Debugging
|
969
|
+
|
970
|
+
One way to check the headers are cached properly in your CDN is by using [curl](
|
971
|
+
http://explainshell.com/explain?cmd=curl+-I+http%3A%2F%2Fwww.example.com). You
|
972
|
+
can request the headers from both your server and your CDN to verify they are
|
973
|
+
the same:
|
974
|
+
|
975
|
+
```
|
976
|
+
$ curl -I http://www.example/assets/application-
|
977
|
+
d0e099e021c95eb0de3615fd1d8c4d83.css
|
978
|
+
HTTP/1.1 200 OK
|
979
|
+
Server: Cowboy
|
980
|
+
Date: Sun, 24 Aug 2014 20:27:50 GMT
|
981
|
+
Connection: keep-alive
|
982
|
+
Last-Modified: Thu, 08 May 2014 01:24:14 GMT
|
983
|
+
Content-Type: text/css
|
984
|
+
Cache-Control: public, max-age=2592000
|
985
|
+
Content-Length: 126560
|
986
|
+
Via: 1.1 vegur
|
987
|
+
```
|
988
|
+
|
989
|
+
Versus the CDN copy.
|
990
|
+
|
991
|
+
```
|
992
|
+
$ curl -I http://mycdnsubdomain.fictional-cdn.com/application-
|
993
|
+
d0e099e021c95eb0de3615fd1d8c4d83.css
|
994
|
+
HTTP/1.1 200 OK Server: Cowboy Last-
|
995
|
+
Modified: Thu, 08 May 2014 01:24:14 GMT Content-Type: text/css
|
996
|
+
Cache-Control:
|
997
|
+
public, max-age=2592000
|
998
|
+
Via: 1.1 vegur
|
999
|
+
Content-Length: 126560
|
1000
|
+
Accept-Ranges:
|
1001
|
+
bytes
|
1002
|
+
Date: Sun, 24 Aug 2014 20:28:45 GMT
|
1003
|
+
Via: 1.1 varnish
|
1004
|
+
Age: 885814
|
1005
|
+
Connection: keep-alive
|
1006
|
+
X-Served-By: cache-dfw1828-DFW
|
1007
|
+
X-Cache: HIT
|
1008
|
+
X-Cache-Hits:
|
1009
|
+
68
|
1010
|
+
X-Timer: S1408912125.211638212,VS0,VE0
|
1011
|
+
```
|
1012
|
+
|
1013
|
+
Check your CDN documentation for any additional information they may provide
|
1014
|
+
such as `X-Cache` or for any additional headers they may add.
|
1015
|
+
|
1016
|
+
##### CDNs and the Cache-Control Header
|
1017
|
+
|
1018
|
+
The [cache control
|
1019
|
+
header](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) is a W3C
|
1020
|
+
specification that describes how a request can be cached. When no CDN is used, a
|
1021
|
+
browser will use this information to cache contents. This is very helpful for
|
1022
|
+
assets that are not modified so that a browser does not need to re-download a
|
1023
|
+
website's CSS or javascript on every request. Generally we want our Rails server
|
1024
|
+
to tell our CDN (and browser) that the asset is "public", that means any cache
|
1025
|
+
can store the request. Also we commonly want to set `max-age` which is how long
|
1026
|
+
the cache will store the object before invalidating the cache. The `max-age`
|
1027
|
+
value is set to seconds with a maximum possible value of `31536000` which is one
|
1028
|
+
year. You can do this in your rails application by setting
|
1029
|
+
|
1030
|
+
```
|
1031
|
+
config.static_cache_control = "public, max-age=31536000"
|
1032
|
+
```
|
1033
|
+
|
1034
|
+
Now when your application serves an asset in production, the CDN will store the
|
1035
|
+
asset for up to a year. Since most CDNs also cache headers of the request, this
|
1036
|
+
`Cache-Control` will be passed along to all future browsers seeking this asset,
|
1037
|
+
the browser then knows that it can store this asset for a very long time before
|
1038
|
+
needing to re-request it.
|
1039
|
+
|
1040
|
+
##### CDNs and URL based Cache Invalidation
|
1041
|
+
|
1042
|
+
Most CDNs will cache contents of an asset based on the complete URL. This means
|
1043
|
+
that a request to
|
1044
|
+
|
1045
|
+
```
|
1046
|
+
http://mycdnsubdomain.fictional-cdn.com/assets/smile-123.png
|
1047
|
+
```
|
1048
|
+
|
1049
|
+
Will be a completely different cache from
|
1050
|
+
|
1051
|
+
```
|
1052
|
+
http://mycdnsubdomain.fictional-cdn.com/assets/smile.png
|
1053
|
+
```
|
1054
|
+
|
1055
|
+
If you want to set far future `max-age` in your `Cache-Control` (and you do),
|
1056
|
+
then make sure when you change your assets that your cache is invalidated. For
|
1057
|
+
example when changing the smiley face in an image from yellow to blue, you want
|
1058
|
+
all visitors of your site to get the new blue face. When using a CDN with the
|
1059
|
+
Rails asset pipeline `config.assets.digest` is set to true by default so that
|
1060
|
+
each asset will have a different file name when it is changed. This way you
|
1061
|
+
don't have to ever manually invalidate any items in your cache. By using a
|
1062
|
+
different unique asset name instead, your users get the latest asset.
|
930
1063
|
|
931
1064
|
Customizing the Pipeline
|
932
1065
|
------------------------
|
@@ -943,7 +1076,7 @@ gem.
|
|
943
1076
|
```ruby
|
944
1077
|
config.assets.css_compressor = :yui
|
945
1078
|
```
|
946
|
-
The other option for compressing CSS if you have the sass-rails gem installed is
|
1079
|
+
The other option for compressing CSS if you have the sass-rails gem installed is
|
947
1080
|
|
948
1081
|
```ruby
|
949
1082
|
config.assets.css_compressor = :sass
|
@@ -967,7 +1100,7 @@ The following line invokes `uglifier` for JavaScript compression.
|
|
967
1100
|
config.assets.js_compressor = :uglifier
|
968
1101
|
```
|
969
1102
|
|
970
|
-
NOTE: You will need an [ExecJS](https://github.com/
|
1103
|
+
NOTE: You will need an [ExecJS](https://github.com/rails/execjs#readme)
|
971
1104
|
supported runtime in order to use `uglifier`. If you are using Mac OS X or
|
972
1105
|
Windows you have a JavaScript runtime installed in your operating system.
|
973
1106
|
|
@@ -1018,15 +1151,15 @@ The X-Sendfile header is a directive to the web server to ignore the response
|
|
1018
1151
|
from the application, and instead serve a specified file from disk. This option
|
1019
1152
|
is off by default, but can be enabled if your server supports it. When enabled,
|
1020
1153
|
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)
|
1154
|
+
faster. Have a look at [send_file](http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_file)
|
1022
1155
|
on how to use this feature.
|
1023
1156
|
|
1024
|
-
Apache and
|
1157
|
+
Apache and NGINX support this option, which can be enabled in
|
1025
1158
|
`config/environments/production.rb`:
|
1026
1159
|
|
1027
1160
|
```ruby
|
1028
|
-
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for
|
1029
|
-
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for
|
1161
|
+
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
|
1162
|
+
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
|
1030
1163
|
```
|
1031
1164
|
|
1032
1165
|
WARNING: If you are upgrading an existing application and intend to use this
|
@@ -1036,7 +1169,7 @@ and any other environments you define with production behavior (not
|
|
1036
1169
|
|
1037
1170
|
TIP: For further details have a look at the docs of your production web server:
|
1038
1171
|
- [Apache](https://tn123.org/mod_xsendfile/)
|
1039
|
-
- [
|
1172
|
+
- [NGINX](http://wiki.nginx.org/XSendfile)
|
1040
1173
|
|
1041
1174
|
Assets Cache Store
|
1042
1175
|
------------------
|
@@ -1056,6 +1189,14 @@ cache store.
|
|
1056
1189
|
config.assets.cache_store = :memory_store, { size: 32.megabytes }
|
1057
1190
|
```
|
1058
1191
|
|
1192
|
+
To disable the assets cache store:
|
1193
|
+
|
1194
|
+
```ruby
|
1195
|
+
config.assets.configure do |env|
|
1196
|
+
env.cache = ActiveSupport::Cache.lookup_store(:null_store)
|
1197
|
+
end
|
1198
|
+
```
|
1199
|
+
|
1059
1200
|
Adding Assets to Your Gems
|
1060
1201
|
--------------------------
|
1061
1202
|
|
@@ -1151,8 +1292,8 @@ config.assets.digest = true
|
|
1151
1292
|
|
1152
1293
|
Rails 4 no longer sets default config values for Sprockets in `test.rb`, so
|
1153
1294
|
`test.rb` now requires Sprockets configuration. The old defaults in the test
|
1154
|
-
environment are: `config.assets.compile = true`, `config.assets.compress =
|
1155
|
-
|
1295
|
+
environment are: `config.assets.compile = true`, `config.assets.compress = false`,
|
1296
|
+
`config.assets.debug = false` and `config.assets.digest = false`.
|
1156
1297
|
|
1157
1298
|
The following should also be added to `Gemfile`:
|
1158
1299
|
|