rails 4.1.6 → 4.2.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +12 -10
- data/guides/CHANGELOG.md +64 -17
- 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 +9 -10
- 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 +25 -8
- 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} +95 -220
- data/guides/source/active_record_postgresql.md +433 -0
- data/guides/source/active_record_querying.md +264 -268
- data/guides/source/active_record_validations.md +23 -13
- 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 +259 -120
- 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 +440 -286
- 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 +359 -219
- data/guides/source/i18n.md +110 -66
- data/guides/source/index.html.erb +1 -0
- data/guides/source/initialization.md +109 -62
- data/guides/source/layout.html.erb +5 -11
- data/guides/source/layouts_and_rendering.md +26 -26
- data/guides/source/maintenance_policy.md +6 -3
- 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 +8 -5
- data/guides/source/routing.md +113 -73
- data/guides/source/ruby_on_rails_guides_guidelines.md +11 -12
- data/guides/source/security.md +40 -34
- data/guides/source/testing.md +199 -119
- data/guides/source/upgrading_ruby_on_rails.md +289 -31
- 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
|
|
@@ -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.
|
@@ -801,7 +777,7 @@ For Apache:
|
|
801
777
|
</Location>
|
802
778
|
```
|
803
779
|
|
804
|
-
For
|
780
|
+
For NGINX:
|
805
781
|
|
806
782
|
```nginx
|
807
783
|
location ~ ^/assets/ {
|
@@ -813,41 +789,6 @@ location ~ ^/assets/ {
|
|
813
789
|
}
|
814
790
|
```
|
815
791
|
|
816
|
-
#### GZip Compression
|
817
|
-
|
818
|
-
When files are precompiled, Sprockets also creates a
|
819
|
-
[gzipped](http://en.wikipedia.org/wiki/Gzip) (.gz) version of your assets. Web
|
820
|
-
servers are typically configured to use a moderate compression ratio as a
|
821
|
-
compromise, but since precompilation happens once, Sprockets uses the maximum
|
822
|
-
compression ratio, thus reducing the size of the data transfer to the minimum.
|
823
|
-
On the other hand, web servers can be configured to serve compressed content
|
824
|
-
directly from disk, rather than deflating non-compressed files themselves.
|
825
|
-
|
826
|
-
Nginx is able to do this automatically enabling `gzip_static`:
|
827
|
-
|
828
|
-
```nginx
|
829
|
-
location ~ ^/(assets)/ {
|
830
|
-
root /path/to/public;
|
831
|
-
gzip_static on; # to serve pre-gzipped version
|
832
|
-
expires max;
|
833
|
-
add_header Cache-Control public;
|
834
|
-
}
|
835
|
-
```
|
836
|
-
|
837
|
-
This directive is available if the core module that provides this feature was
|
838
|
-
compiled with the web server. Ubuntu/Debian packages, even `nginx-light`, have
|
839
|
-
the module compiled. Otherwise, you may need to perform a manual compilation:
|
840
|
-
|
841
|
-
```bash
|
842
|
-
./configure --with-http_gzip_static_module
|
843
|
-
```
|
844
|
-
|
845
|
-
If you're compiling nginx with Phusion Passenger you'll need to pass that option
|
846
|
-
when prompted.
|
847
|
-
|
848
|
-
A robust configuration for Apache is possible but tricky; please Google around.
|
849
|
-
(Or help update this Guide if you have a good configuration example for Apache.)
|
850
|
-
|
851
792
|
### Local Precompilation
|
852
793
|
|
853
794
|
There are several reasons why you might want to precompile your assets locally.
|
@@ -861,10 +802,12 @@ duplication of work.
|
|
861
802
|
Local compilation allows you to commit the compiled files into source control,
|
862
803
|
and deploy as normal.
|
863
804
|
|
864
|
-
There are
|
805
|
+
There are three caveats:
|
865
806
|
|
866
807
|
* You must not run the Capistrano deployment task that precompiles assets.
|
867
|
-
* 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:
|
868
811
|
|
869
812
|
In `config/environments/development.rb`, place the following line:
|
870
813
|
|
@@ -878,9 +821,6 @@ development mode, and pass all requests to Sprockets. The prefix is still set to
|
|
878
821
|
would serve the precompiled assets from `/assets` in development, and you would
|
879
822
|
not see any local changes until you compile assets again.
|
880
823
|
|
881
|
-
You will also need to ensure any necessary compressors or minifiers are
|
882
|
-
available on your development system.
|
883
|
-
|
884
824
|
In practice, this will allow you to precompile locally, have those files in your
|
885
825
|
working tree, and commit those files to source control when needed. Development
|
886
826
|
mode will work as expected.
|
@@ -920,15 +860,206 @@ end
|
|
920
860
|
|
921
861
|
### CDNs
|
922
862
|
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
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
|
+
|
927
920
|
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
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.
|
932
1063
|
|
933
1064
|
Customizing the Pipeline
|
934
1065
|
------------------------
|
@@ -969,7 +1100,7 @@ The following line invokes `uglifier` for JavaScript compression.
|
|
969
1100
|
config.assets.js_compressor = :uglifier
|
970
1101
|
```
|
971
1102
|
|
972
|
-
NOTE: You will need an [ExecJS](https://github.com/
|
1103
|
+
NOTE: You will need an [ExecJS](https://github.com/rails/execjs#readme)
|
973
1104
|
supported runtime in order to use `uglifier`. If you are using Mac OS X or
|
974
1105
|
Windows you have a JavaScript runtime installed in your operating system.
|
975
1106
|
|
@@ -1023,12 +1154,12 @@ this passes responsibility for serving the file to the web server, which is
|
|
1023
1154
|
faster. Have a look at [send_file](http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_file)
|
1024
1155
|
on how to use this feature.
|
1025
1156
|
|
1026
|
-
Apache and
|
1157
|
+
Apache and NGINX support this option, which can be enabled in
|
1027
1158
|
`config/environments/production.rb`:
|
1028
1159
|
|
1029
1160
|
```ruby
|
1030
|
-
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for
|
1031
|
-
# 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
|
1032
1163
|
```
|
1033
1164
|
|
1034
1165
|
WARNING: If you are upgrading an existing application and intend to use this
|
@@ -1038,7 +1169,7 @@ and any other environments you define with production behavior (not
|
|
1038
1169
|
|
1039
1170
|
TIP: For further details have a look at the docs of your production web server:
|
1040
1171
|
- [Apache](https://tn123.org/mod_xsendfile/)
|
1041
|
-
- [
|
1172
|
+
- [NGINX](http://wiki.nginx.org/XSendfile)
|
1042
1173
|
|
1043
1174
|
Assets Cache Store
|
1044
1175
|
------------------
|
@@ -1058,6 +1189,14 @@ cache store.
|
|
1058
1189
|
config.assets.cache_store = :memory_store, { size: 32.megabytes }
|
1059
1190
|
```
|
1060
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
|
+
|
1061
1200
|
Adding Assets to Your Gems
|
1062
1201
|
--------------------------
|
1063
1202
|
|
@@ -1153,8 +1292,8 @@ config.assets.digest = true
|
|
1153
1292
|
|
1154
1293
|
Rails 4 no longer sets default config values for Sprockets in `test.rb`, so
|
1155
1294
|
`test.rb` now requires Sprockets configuration. The old defaults in the test
|
1156
|
-
environment are: `config.assets.compile = true`, `config.assets.compress =
|
1157
|
-
|
1295
|
+
environment are: `config.assets.compile = true`, `config.assets.compress = false`,
|
1296
|
+
`config.assets.debug = false` and `config.assets.digest = false`.
|
1158
1297
|
|
1159
1298
|
The following should also be added to `Gemfile`:
|
1160
1299
|
|