rails 4.1.16 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -10
- data/guides/CHANGELOG.md +15 -100
- data/guides/Rakefile +5 -3
- data/guides/assets/javascripts/guides.js +6 -0
- data/guides/assets/stylesheets/main.css +4 -1
- data/guides/bug_report_templates/action_controller_master.rb +1 -0
- data/guides/rails_guides/helpers.rb +1 -1
- data/guides/rails_guides/levenshtein.rb +29 -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 +5 -6
- data/guides/source/4_2_release_notes.md +850 -0
- data/guides/source/_license.html.erb +1 -1
- data/guides/source/_welcome.html.erb +2 -8
- data/guides/source/action_controller_overview.md +81 -7
- data/guides/source/action_mailer_basics.md +91 -28
- data/guides/source/action_view_overview.md +148 -130
- data/guides/source/active_job_basics.md +318 -0
- data/guides/source/active_model_basics.md +371 -17
- data/guides/source/active_record_basics.md +19 -18
- 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 +263 -265
- data/guides/source/active_record_validations.md +20 -11
- data/guides/source/active_support_core_extensions.md +159 -72
- data/guides/source/active_support_instrumentation.md +10 -7
- data/guides/source/api_documentation_guidelines.md +62 -16
- data/guides/source/asset_pipeline.md +258 -63
- data/guides/source/association_basics.md +81 -74
- data/guides/source/caching_with_rails.md +32 -7
- data/guides/source/command_line.md +52 -30
- data/guides/source/configuring.md +132 -29
- data/guides/source/constant_autoloading_and_reloading.md +1297 -0
- data/guides/source/contributing_to_ruby_on_rails.md +192 -112
- 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 +182 -182
- data/guides/source/form_helpers.md +79 -56
- data/guides/source/generators.md +24 -11
- data/guides/source/getting_started.md +337 -198
- data/guides/source/i18n.md +108 -65
- data/guides/source/index.html.erb +1 -0
- data/guides/source/initialization.md +108 -61
- data/guides/source/layout.html.erb +1 -4
- data/guides/source/layouts_and_rendering.md +27 -25
- 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 -4
- data/guides/source/routing.md +98 -72
- data/guides/source/ruby_on_rails_guides_guidelines.md +11 -12
- data/guides/source/security.md +38 -32
- data/guides/source/testing.md +188 -117
- data/guides/source/upgrading_ruby_on_rails.md +254 -28
- data/guides/source/working_with_javascript_in_rails.md +18 -16
- data/guides/w3c_validator.rb +2 -0
- metadata +40 -96
- data/guides/bug_report_templates/generic_gem.rb +0 -15
- data/guides/bug_report_templates/generic_master.rb +0 -26
- 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
@@ -13,7 +13,19 @@ After reading this guide, you will know:
|
|
13
13
|
RDoc
|
14
14
|
----
|
15
15
|
|
16
|
-
The Rails API documentation
|
16
|
+
The [Rails API documentation](http://api.rubyonrails.org) is generated with
|
17
|
+
[RDoc](http://docs.seattlerb.org/rdoc/).
|
18
|
+
|
19
|
+
```bash
|
20
|
+
bundle exec rake rdoc
|
21
|
+
```
|
22
|
+
|
23
|
+
Resulting HTML files can be found in the ./doc/rdoc directory.
|
24
|
+
|
25
|
+
Please consult the RDoc documentation for help with the
|
26
|
+
[markup](http://docs.seattlerb.org/rdoc/RDoc/Markup.html),
|
27
|
+
and also take into account these [additional
|
28
|
+
directives](http://docs.seattlerb.org/rdoc/RDoc/Parser/Ruby.html).
|
17
29
|
|
18
30
|
Wording
|
19
31
|
-------
|
@@ -67,7 +79,7 @@ used. Instead of:
|
|
67
79
|
English
|
68
80
|
-------
|
69
81
|
|
70
|
-
Please use American English (
|
82
|
+
Please use American English (*color*, *center*, *modularize*, etc). See [a list of American and British English spelling differences here](http://en.wikipedia.org/wiki/American_and_British_English_spelling_differences).
|
71
83
|
|
72
84
|
Example Code
|
73
85
|
------------
|
@@ -110,14 +122,14 @@ The results of expressions follow them and are introduced by "# => ", vertically
|
|
110
122
|
If a line is too long, the comment may be placed on the next line:
|
111
123
|
|
112
124
|
```ruby
|
113
|
-
# label(:
|
114
|
-
# # => <label for="
|
125
|
+
# label(:article, :title)
|
126
|
+
# # => <label for="article_title">Title</label>
|
115
127
|
#
|
116
|
-
# label(:
|
117
|
-
# # => <label for="
|
128
|
+
# label(:article, :title, "A short title")
|
129
|
+
# # => <label for="article_title">A short title</label>
|
118
130
|
#
|
119
|
-
# label(:
|
120
|
-
# # => <label for="
|
131
|
+
# label(:article, :title, "A short title", class: "title_label")
|
132
|
+
# # => <label for="article_title" class="title_label">A short title</label>
|
121
133
|
```
|
122
134
|
|
123
135
|
Avoid using any printing methods like `puts` or `p` for that purpose.
|
@@ -175,8 +187,8 @@ end
|
|
175
187
|
The API is careful not to commit to any particular value, the method has
|
176
188
|
predicate semantics, that's enough.
|
177
189
|
|
178
|
-
|
179
|
-
|
190
|
+
File Names
|
191
|
+
----------
|
180
192
|
|
181
193
|
As a rule of thumb, use filenames relative to the application root:
|
182
194
|
|
@@ -215,6 +227,13 @@ ordinary method names, symbols, paths (with forward slashes), etc. Please use
|
|
215
227
|
`<tt>...</tt>` for everything else, notably class or module names with a
|
216
228
|
namespace as in `<tt>ActiveRecord::Base</tt>`.
|
217
229
|
|
230
|
+
You can quickly test the RDoc output with the following command:
|
231
|
+
|
232
|
+
```
|
233
|
+
$ echo "+:to_param+" | rdoc --pipe
|
234
|
+
#=> <p><code>:to_param</code></p>
|
235
|
+
```
|
236
|
+
|
218
237
|
### Regular Font
|
219
238
|
|
220
239
|
When "true" and "false" are English words rather than Ruby keywords use a regular font:
|
@@ -283,7 +302,7 @@ self.class_eval %{
|
|
283
302
|
Method Visibility
|
284
303
|
-----------------
|
285
304
|
|
286
|
-
When writing documentation for Rails, it's important to understand the difference between public
|
305
|
+
When writing documentation for Rails, it's important to understand the difference between public user-facing API vs internal API.
|
287
306
|
|
288
307
|
Rails, like most libraries, uses the private keyword from Ruby for defining internal API. However, public API follows a slightly different convention. Instead of assuming all public methods are designed for user consumption, Rails uses the `:nodoc:` directive to annotate these kinds of methods as internal API.
|
289
308
|
|
@@ -299,17 +318,44 @@ module ActiveRecord::Core::ClassMethods
|
|
299
318
|
end
|
300
319
|
```
|
301
320
|
|
302
|
-
If you thought, "this method looks like a public class method for `ActiveRecord::Core`", you were right. But actually the Rails team doesn't want users to rely on this method. So they mark it as `:nodoc:` and it's removed from public documentation. The reasoning behind this is to allow the team to change these methods according to their internal needs across releases as they see fit. The name of this method could change, or the return value, or this entire class may disappear; there's no guarantee and so you shouldn't depend on this API in your
|
321
|
+
If you thought, "this method looks like a public class method for `ActiveRecord::Core`", you were right. But actually the Rails team doesn't want users to rely on this method. So they mark it as `:nodoc:` and it's removed from public documentation. The reasoning behind this is to allow the team to change these methods according to their internal needs across releases as they see fit. The name of this method could change, or the return value, or this entire class may disappear; there's no guarantee and so you shouldn't depend on this API in your plugins or applications. Otherwise, you risk your app or gem breaking when you upgrade to a newer release of Rails.
|
303
322
|
|
304
|
-
As a contributor, it's important to think about whether this API is meant for end-user consumption. The Rails team is committed to not making any breaking changes to public API across releases without going through a full deprecation cycle
|
323
|
+
As a contributor, it's important to think about whether this API is meant for end-user consumption. The Rails team is committed to not making any breaking changes to public API across releases without going through a full deprecation cycle. It's recommended that you `:nodoc:` any of your internal methods/classes unless they're already private (meaning visibility), in which case it's internal by default. Once the API stabilizes the visibility can change, but changing public API is much harder due to backwards compatibility.
|
305
324
|
|
306
325
|
A class or module is marked with `:nodoc:` to indicate that all methods are internal API and should never be used directly.
|
307
326
|
|
308
|
-
If you come across an existing `:nodoc:` you should tread lightly. Consider asking someone from the core team or author of the code before removing it. This should almost always happen through a
|
327
|
+
If you come across an existing `:nodoc:` you should tread lightly. Consider asking someone from the core team or author of the code before removing it. This should almost always happen through a pull request instead of the docrails project.
|
309
328
|
|
310
329
|
A `:nodoc:` should never be added simply because a method or class is missing documentation. There may be an instance where an internal public method wasn't given a `:nodoc:` by mistake, for example when switching a method from private to public visibility. When this happens it should be discussed over a PR on a case-by-case basis and never committed directly to docrails.
|
311
330
|
|
312
|
-
To summarize, the Rails team uses `:nodoc:` to mark publicly visible methods and classes for internal use; changes to the visibility of API should be considered carefully and discussed over a
|
331
|
+
To summarize, the Rails team uses `:nodoc:` to mark publicly visible methods and classes for internal use; changes to the visibility of API should be considered carefully and discussed over a pull request first.
|
332
|
+
|
333
|
+
Regarding the Rails Stack
|
334
|
+
-------------------------
|
335
|
+
|
336
|
+
When documenting parts of Rails API, it's important to remember all of the
|
337
|
+
pieces that go into the Rails stack.
|
338
|
+
|
339
|
+
This means that behavior may change depending on the scope or context of the
|
340
|
+
method or class you're trying to document.
|
341
|
+
|
342
|
+
In various places there is different behavior when you take the entire stack
|
343
|
+
into account, one such example is
|
344
|
+
`ActionView::Helpers::AssetTagHelper#image_tag`:
|
345
|
+
|
346
|
+
```ruby
|
347
|
+
# image_tag("icon.png")
|
348
|
+
# # => <img alt="Icon" src="/assets/icon.png" />
|
349
|
+
```
|
350
|
+
|
351
|
+
Although the default behavior for `#image_tag` is to always return
|
352
|
+
`/images/icon.png`, we take into account the full Rails stack (including the
|
353
|
+
Asset Pipeline) we may see the result seen above.
|
354
|
+
|
355
|
+
We're only concerned with the behavior experienced when using the full default
|
356
|
+
Rails stack.
|
313
357
|
|
314
|
-
|
358
|
+
In this case, we want to document the behavior of the _framework_, and not just
|
359
|
+
this specific method.
|
315
360
|
|
361
|
+
If you have a question on how the Rails team handles certain API, don't hesitate to open a ticket or send a patch to the [issue tracker](https://github.com/rails/rails/issues).
|
@@ -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/rails/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.
|
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
|
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
|
-
|
588
|
+
### Turning Digests Off
|
587
589
|
|
588
|
-
|
589
|
-
|
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
|
-
```
|
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
|
|
@@ -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
|
-
|
739
|
+
logger.info "including asset: " + full_path
|
743
740
|
true
|
744
741
|
else
|
745
|
-
|
742
|
+
logger.info "excluding asset: " + full_path
|
746
743
|
false
|
747
744
|
end
|
748
745
|
else
|
@@ -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
|
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.
|
@@ -801,7 +798,7 @@ For Apache:
|
|
801
798
|
</Location>
|
802
799
|
```
|
803
800
|
|
804
|
-
For
|
801
|
+
For NGINX:
|
805
802
|
|
806
803
|
```nginx
|
807
804
|
location ~ ^/assets/ {
|
@@ -823,7 +820,7 @@ compression ratio, thus reducing the size of the data transfer to the minimum.
|
|
823
820
|
On the other hand, web servers can be configured to serve compressed content
|
824
821
|
directly from disk, rather than deflating non-compressed files themselves.
|
825
822
|
|
826
|
-
|
823
|
+
NGINX is able to do this automatically enabling `gzip_static`:
|
827
824
|
|
828
825
|
```nginx
|
829
826
|
location ~ ^/(assets)/ {
|
@@ -842,7 +839,7 @@ the module compiled. Otherwise, you may need to perform a manual compilation:
|
|
842
839
|
./configure --with-http_gzip_static_module
|
843
840
|
```
|
844
841
|
|
845
|
-
If you're compiling
|
842
|
+
If you're compiling NGINX with Phusion Passenger you'll need to pass that option
|
846
843
|
when prompted.
|
847
844
|
|
848
845
|
A robust configuration for Apache is possible but tricky; please Google around.
|
@@ -861,10 +858,12 @@ duplication of work.
|
|
861
858
|
Local compilation allows you to commit the compiled files into source control,
|
862
859
|
and deploy as normal.
|
863
860
|
|
864
|
-
There are
|
861
|
+
There are three caveats:
|
865
862
|
|
866
863
|
* You must not run the Capistrano deployment task that precompiles assets.
|
867
|
-
* You must
|
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:
|
868
867
|
|
869
868
|
In `config/environments/development.rb`, place the following line:
|
870
869
|
|
@@ -878,9 +877,6 @@ development mode, and pass all requests to Sprockets. The prefix is still set to
|
|
878
877
|
would serve the precompiled assets from `/assets` in development, and you would
|
879
878
|
not see any local changes until you compile assets again.
|
880
879
|
|
881
|
-
You will also need to ensure any necessary compressors or minifiers are
|
882
|
-
available on your development system.
|
883
|
-
|
884
880
|
In practice, this will allow you to precompile locally, have those files in your
|
885
881
|
working tree, and commit those files to source control when needed. Development
|
886
882
|
mode will work as expected.
|
@@ -920,15 +916,206 @@ end
|
|
920
916
|
|
921
917
|
### CDNs
|
922
918
|
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
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
|
+
|
927
976
|
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
you
|
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.
|
932
1119
|
|
933
1120
|
Customizing the Pipeline
|
934
1121
|
------------------------
|
@@ -969,7 +1156,7 @@ The following line invokes `uglifier` for JavaScript compression.
|
|
969
1156
|
config.assets.js_compressor = :uglifier
|
970
1157
|
```
|
971
1158
|
|
972
|
-
NOTE: You will need an [ExecJS](https://github.com/
|
1159
|
+
NOTE: You will need an [ExecJS](https://github.com/sstephenson/execjs#readme)
|
973
1160
|
supported runtime in order to use `uglifier`. If you are using Mac OS X or
|
974
1161
|
Windows you have a JavaScript runtime installed in your operating system.
|
975
1162
|
|
@@ -1023,12 +1210,12 @@ this passes responsibility for serving the file to the web server, which is
|
|
1023
1210
|
faster. Have a look at [send_file](http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_file)
|
1024
1211
|
on how to use this feature.
|
1025
1212
|
|
1026
|
-
Apache and
|
1213
|
+
Apache and NGINX support this option, which can be enabled in
|
1027
1214
|
`config/environments/production.rb`:
|
1028
1215
|
|
1029
1216
|
```ruby
|
1030
|
-
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for
|
1031
|
-
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for
|
1217
|
+
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
|
1218
|
+
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
|
1032
1219
|
```
|
1033
1220
|
|
1034
1221
|
WARNING: If you are upgrading an existing application and intend to use this
|
@@ -1038,7 +1225,7 @@ and any other environments you define with production behavior (not
|
|
1038
1225
|
|
1039
1226
|
TIP: For further details have a look at the docs of your production web server:
|
1040
1227
|
- [Apache](https://tn123.org/mod_xsendfile/)
|
1041
|
-
- [
|
1228
|
+
- [NGINX](http://wiki.nginx.org/XSendfile)
|
1042
1229
|
|
1043
1230
|
Assets Cache Store
|
1044
1231
|
------------------
|
@@ -1058,6 +1245,14 @@ cache store.
|
|
1058
1245
|
config.assets.cache_store = :memory_store, { size: 32.megabytes }
|
1059
1246
|
```
|
1060
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
|
+
|
1061
1256
|
Adding Assets to Your Gems
|
1062
1257
|
--------------------------
|
1063
1258
|
|
@@ -1153,8 +1348,8 @@ config.assets.digest = true
|
|
1153
1348
|
|
1154
1349
|
Rails 4 no longer sets default config values for Sprockets in `test.rb`, so
|
1155
1350
|
`test.rb` now requires Sprockets configuration. The old defaults in the test
|
1156
|
-
environment are: `config.assets.compile = true`, `config.assets.compress =
|
1157
|
-
|
1351
|
+
environment are: `config.assets.compile = true`, `config.assets.compress = false`,
|
1352
|
+
`config.assets.debug = false` and `config.assets.digest = false`.
|
1158
1353
|
|
1159
1354
|
The following should also be added to `Gemfile`:
|
1160
1355
|
|