rails 4.2.0 → 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/guides/CHANGELOG.md +82 -0
- data/guides/Rakefile +16 -3
- data/guides/assets/images/getting_started/article_with_comments.png +0 -0
- data/guides/bug_report_templates/action_controller_gem.rb +1 -1
- 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/levenshtein.rb +0 -2
- data/guides/source/3_1_release_notes.md +1 -1
- data/guides/source/4_2_release_notes.md +27 -0
- data/guides/source/_welcome.html.erb +5 -1
- data/guides/source/action_controller_overview.md +2 -59
- data/guides/source/action_mailer_basics.md +8 -3
- data/guides/source/action_view_overview.md +2 -61
- data/guides/source/active_job_basics.md +27 -6
- data/guides/source/active_record_basics.md +6 -6
- data/guides/source/active_record_querying.md +1 -3
- data/guides/source/active_record_validations.md +3 -2
- data/guides/source/active_support_core_extensions.md +2 -50
- data/guides/source/active_support_instrumentation.md +0 -11
- data/guides/source/api_documentation_guidelines.md +1 -1
- data/guides/source/asset_pipeline.md +7 -63
- data/guides/source/association_basics.md +16 -7
- data/guides/source/{constant_autoloading_and_reloading.md → autoloading_and_reloading_constants.md} +42 -28
- data/guides/source/configuring.md +30 -5
- data/guides/source/contributing_to_ruby_on_rails.md +7 -3
- data/guides/source/documents.yaml +3 -3
- data/guides/source/engines.md +10 -10
- data/guides/source/getting_started.md +33 -32
- data/guides/source/i18n.md +3 -2
- data/guides/source/initialization.md +1 -1
- data/guides/source/layout.html.erb +4 -7
- data/guides/source/layouts_and_rendering.md +8 -9
- data/guides/source/rails_on_rack.md +0 -1
- data/guides/source/routing.md +15 -1
- data/guides/source/security.md +1 -1
- data/guides/source/testing.md +12 -3
- data/guides/source/upgrading_ruby_on_rails.md +35 -3
- data/guides/source/working_with_javascript_in_rails.md +1 -1
- metadata +22 -21
@@ -65,33 +65,41 @@ Here's what a job looks like:
|
|
65
65
|
class GuestsCleanupJob < ActiveJob::Base
|
66
66
|
queue_as :default
|
67
67
|
|
68
|
-
def perform(*
|
68
|
+
def perform(*guests)
|
69
69
|
# Do something later
|
70
70
|
end
|
71
71
|
end
|
72
72
|
```
|
73
73
|
|
74
|
+
Note that you can define `perform` with as many arguments as you want.
|
75
|
+
|
74
76
|
### Enqueue the Job
|
75
77
|
|
76
78
|
Enqueue a job like so:
|
77
79
|
|
78
80
|
```ruby
|
79
|
-
# Enqueue a job to be performed as soon the
|
80
|
-
|
81
|
+
# Enqueue a job to be performed as soon the queuing system is
|
82
|
+
# free.
|
83
|
+
GuestsCleanupJob.perform_later guest
|
81
84
|
```
|
82
85
|
|
83
86
|
```ruby
|
84
87
|
# Enqueue a job to be performed tomorrow at noon.
|
85
|
-
|
88
|
+
GuestsCleanupJob.set(wait_until: Date.tomorrow.noon).perform_later(guest)
|
86
89
|
```
|
87
90
|
|
88
91
|
```ruby
|
89
92
|
# Enqueue a job to be performed 1 week from now.
|
90
|
-
|
93
|
+
GuestsCleanupJob.set(wait: 1.week).perform_later(guest)
|
91
94
|
```
|
92
95
|
|
93
|
-
|
96
|
+
```ruby
|
97
|
+
# `perform_now` and `perform_later` will call `perform` under the hood so
|
98
|
+
# you can pass as many arguments as defined in the latter.
|
99
|
+
GuestsCleanupJob.perform_later(guest1, guest2, filter: 'some_filter')
|
100
|
+
```
|
94
101
|
|
102
|
+
That's it!
|
95
103
|
|
96
104
|
Job Execution
|
97
105
|
-------------
|
@@ -266,6 +274,19 @@ UserMailer.welcome(@user).deliver_later
|
|
266
274
|
```
|
267
275
|
|
268
276
|
|
277
|
+
Internationalization
|
278
|
+
--------------------
|
279
|
+
|
280
|
+
Each job uses the `I18n.locale` set when the job was created. Useful if you send
|
281
|
+
emails asynchronously:
|
282
|
+
|
283
|
+
```ruby
|
284
|
+
I18n.locale = :eo
|
285
|
+
|
286
|
+
UserMailer.welcome(@user).deliver_later # Email will be localized to Esparanto.
|
287
|
+
```
|
288
|
+
|
289
|
+
|
269
290
|
GlobalID
|
270
291
|
--------
|
271
292
|
|
@@ -171,18 +171,18 @@ name that should be used:
|
|
171
171
|
|
172
172
|
```ruby
|
173
173
|
class Product < ActiveRecord::Base
|
174
|
-
self.table_name = "
|
174
|
+
self.table_name = "my_products"
|
175
175
|
end
|
176
176
|
```
|
177
177
|
|
178
178
|
If you do so, you will have to define manually the class name that is hosting
|
179
|
-
the fixtures (
|
179
|
+
the fixtures (my_products.yml) using the `set_fixture_class` method in your test
|
180
180
|
definition:
|
181
181
|
|
182
182
|
```ruby
|
183
|
-
class
|
184
|
-
set_fixture_class
|
185
|
-
fixtures :
|
183
|
+
class ProductTest < ActiveSupport::TestCase
|
184
|
+
set_fixture_class my_products: Product
|
185
|
+
fixtures :my_products
|
186
186
|
...
|
187
187
|
end
|
188
188
|
```
|
@@ -258,7 +258,7 @@ david = User.find_by(name: 'David')
|
|
258
258
|
|
259
259
|
```ruby
|
260
260
|
# find all users named David who are Code Artists and sort by created_at in reverse chronological order
|
261
|
-
users = User.where(name: 'David', occupation: 'Code Artist').order(
|
261
|
+
users = User.where(name: 'David', occupation: 'Code Artist').order(created_at: :desc)
|
262
262
|
```
|
263
263
|
|
264
264
|
You can learn more about querying an Active Record model in the [Active Record
|
@@ -332,8 +332,6 @@ User.find_each(start: 2000, batch_size: 5000) do |user|
|
|
332
332
|
end
|
333
333
|
```
|
334
334
|
|
335
|
-
Another example would be if you wanted multiple workers handling the same processing queue. You could have each worker handle 10000 records by setting the appropriate `:start` option on each worker.
|
336
|
-
|
337
335
|
#### `find_in_batches`
|
338
336
|
|
339
337
|
The `find_in_batches` method is similar to `find_each`, since both retrieve batches of records. The difference is that `find_in_batches` yields _batches_ to the block as an array of models, instead of individually. The following example will yield to the supplied block an array of up to 1000 invoices at a time, with the final block containing any remaining invoices:
|
@@ -876,7 +874,7 @@ For example:
|
|
876
874
|
Item.transaction do
|
877
875
|
i = Item.lock.first
|
878
876
|
i.name = 'Jones'
|
879
|
-
i.save
|
877
|
+
i.save!
|
880
878
|
end
|
881
879
|
```
|
882
880
|
|
@@ -944,8 +944,9 @@ own custom validators.
|
|
944
944
|
|
945
945
|
You can also create methods that verify the state of your models and add
|
946
946
|
messages to the `errors` collection when they are invalid. You must then
|
947
|
-
register these methods by using the `validate`
|
948
|
-
|
947
|
+
register these methods by using the `validate`
|
948
|
+
([API](http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validate))
|
949
|
+
class method, passing in the symbols for the validation methods' names.
|
949
950
|
|
950
951
|
You can pass more than one symbol for each class method and the respective
|
951
952
|
validations will be run in the same order as they were registered.
|
@@ -1760,7 +1760,7 @@ NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
|
|
1760
1760
|
The method `constantize` resolves the constant reference expression in its receiver:
|
1761
1761
|
|
1762
1762
|
```ruby
|
1763
|
-
"
|
1763
|
+
"Integer".constantize # => Integer
|
1764
1764
|
|
1765
1765
|
module M
|
1766
1766
|
X = 1
|
@@ -2612,8 +2612,7 @@ To do so, the method loops over the pairs and builds nodes that depend on the _v
|
|
2612
2612
|
```ruby
|
2613
2613
|
XML_TYPE_NAMES = {
|
2614
2614
|
"Symbol" => "symbol",
|
2615
|
-
"
|
2616
|
-
"Bignum" => "integer",
|
2615
|
+
"Integer" => "integer",
|
2617
2616
|
"BigDecimal" => "decimal",
|
2618
2617
|
"Float" => "float",
|
2619
2618
|
"TrueClass" => "boolean",
|
@@ -3043,53 +3042,6 @@ The method `Range#overlaps?` says whether any two given ranges have non-void int
|
|
3043
3042
|
|
3044
3043
|
NOTE: Defined in `active_support/core_ext/range/overlaps.rb`.
|
3045
3044
|
|
3046
|
-
Extensions to `Proc`
|
3047
|
-
--------------------
|
3048
|
-
|
3049
|
-
### `bind`
|
3050
|
-
|
3051
|
-
As you surely know Ruby has an `UnboundMethod` class whose instances are methods that belong to the limbo of methods without a self. The method `Module#instance_method` returns an unbound method for example:
|
3052
|
-
|
3053
|
-
```ruby
|
3054
|
-
Hash.instance_method(:delete) # => #<UnboundMethod: Hash#delete>
|
3055
|
-
```
|
3056
|
-
|
3057
|
-
An unbound method is not callable as is, you need to bind it first to an object with `bind`:
|
3058
|
-
|
3059
|
-
```ruby
|
3060
|
-
clear = Hash.instance_method(:clear)
|
3061
|
-
clear.bind({a: 1}).call # => {}
|
3062
|
-
```
|
3063
|
-
|
3064
|
-
Active Support defines `Proc#bind` with an analogous purpose:
|
3065
|
-
|
3066
|
-
```ruby
|
3067
|
-
Proc.new { size }.bind([]).call # => 0
|
3068
|
-
```
|
3069
|
-
|
3070
|
-
As you see that's callable and bound to the argument, the return value is indeed a `Method`.
|
3071
|
-
|
3072
|
-
NOTE: To do so `Proc#bind` actually creates a method under the hood. If you ever see a method with a weird name like `__bind_1256598120_237302` in a stack trace you know now where it comes from.
|
3073
|
-
|
3074
|
-
Action Pack uses this trick in `rescue_from` for example, which accepts the name of a method and also a proc as callbacks for a given rescued exception. It has to call them in either case, so a bound method is returned by `handler_for_rescue`, thus simplifying the code in the caller:
|
3075
|
-
|
3076
|
-
```ruby
|
3077
|
-
def handler_for_rescue(exception)
|
3078
|
-
_, rescuer = Array(rescue_handlers).reverse.detect do |klass_name, handler|
|
3079
|
-
...
|
3080
|
-
end
|
3081
|
-
|
3082
|
-
case rescuer
|
3083
|
-
when Symbol
|
3084
|
-
method(rescuer)
|
3085
|
-
when Proc
|
3086
|
-
rescuer.bind(self)
|
3087
|
-
end
|
3088
|
-
end
|
3089
|
-
```
|
3090
|
-
|
3091
|
-
NOTE: Defined in `active_support/core_ext/proc.rb`.
|
3092
|
-
|
3093
3045
|
Extensions to `Date`
|
3094
3046
|
--------------------
|
3095
3047
|
|
@@ -305,17 +305,6 @@ Action Mailer
|
|
305
305
|
}
|
306
306
|
```
|
307
307
|
|
308
|
-
ActiveResource
|
309
|
-
--------------
|
310
|
-
|
311
|
-
### request.active_resource
|
312
|
-
|
313
|
-
| Key | Value |
|
314
|
-
| -------------- | -------------------- |
|
315
|
-
| `:method` | HTTP method |
|
316
|
-
| `:request_uri` | Complete URI |
|
317
|
-
| `:result` | HTTP response object |
|
318
|
-
|
319
308
|
Active Support
|
320
309
|
--------------
|
321
310
|
|
@@ -111,7 +111,7 @@ On the other hand, big chunks of structured documentation may have a separate "E
|
|
111
111
|
The results of expressions follow them and are introduced by "# => ", vertically aligned:
|
112
112
|
|
113
113
|
```ruby
|
114
|
-
# For checking if
|
114
|
+
# For checking if an integer is even or odd.
|
115
115
|
#
|
116
116
|
# 1.even? # => false
|
117
117
|
# 1.odd? # => true
|
@@ -207,7 +207,7 @@ 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 [ExecJS](https://github.com/
|
210
|
+
your operating system. Check [ExecJS](https://github.com/rails/execjs#readme) documentation to know all supported JavaScript runtimes.
|
211
211
|
|
212
212
|
You can also disable generation of controller specific asset files by adding the
|
213
213
|
following to your `config/application.rb` configuration:
|
@@ -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
|
@@ -727,27 +727,6 @@ include, you can add them to the `precompile` array in `config/initializers/asse
|
|
727
727
|
Rails.application.config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']
|
728
728
|
```
|
729
729
|
|
730
|
-
Or, you can opt to precompile all assets with something like this:
|
731
|
-
|
732
|
-
```ruby
|
733
|
-
# config/initializers/assets.rb
|
734
|
-
Rails.application.config.assets.precompile << Proc.new do |path|
|
735
|
-
if path =~ /\.(css|js)\z/
|
736
|
-
full_path = Rails.application.assets.resolve(path).to_path
|
737
|
-
app_assets_path = Rails.root.join('app', 'assets').to_path
|
738
|
-
if full_path.starts_with? app_assets_path
|
739
|
-
logger.info "including asset: " + full_path
|
740
|
-
true
|
741
|
-
else
|
742
|
-
logger.info "excluding asset: " + full_path
|
743
|
-
false
|
744
|
-
end
|
745
|
-
else
|
746
|
-
false
|
747
|
-
end
|
748
|
-
end
|
749
|
-
```
|
750
|
-
|
751
730
|
NOTE. Always specify an expected compiled filename that ends with .js or .css,
|
752
731
|
even if you want to add Sass or CoffeeScript files to the precompile array.
|
753
732
|
|
@@ -810,41 +789,6 @@ location ~ ^/assets/ {
|
|
810
789
|
}
|
811
790
|
```
|
812
791
|
|
813
|
-
#### GZip Compression
|
814
|
-
|
815
|
-
When files are precompiled, Sprockets also creates a
|
816
|
-
[gzipped](http://en.wikipedia.org/wiki/Gzip) (.gz) version of your assets. Web
|
817
|
-
servers are typically configured to use a moderate compression ratio as a
|
818
|
-
compromise, but since precompilation happens once, Sprockets uses the maximum
|
819
|
-
compression ratio, thus reducing the size of the data transfer to the minimum.
|
820
|
-
On the other hand, web servers can be configured to serve compressed content
|
821
|
-
directly from disk, rather than deflating non-compressed files themselves.
|
822
|
-
|
823
|
-
NGINX is able to do this automatically enabling `gzip_static`:
|
824
|
-
|
825
|
-
```nginx
|
826
|
-
location ~ ^/(assets)/ {
|
827
|
-
root /path/to/public;
|
828
|
-
gzip_static on; # to serve pre-gzipped version
|
829
|
-
expires max;
|
830
|
-
add_header Cache-Control public;
|
831
|
-
}
|
832
|
-
```
|
833
|
-
|
834
|
-
This directive is available if the core module that provides this feature was
|
835
|
-
compiled with the web server. Ubuntu/Debian packages, even `nginx-light`, have
|
836
|
-
the module compiled. Otherwise, you may need to perform a manual compilation:
|
837
|
-
|
838
|
-
```bash
|
839
|
-
./configure --with-http_gzip_static_module
|
840
|
-
```
|
841
|
-
|
842
|
-
If you're compiling NGINX with Phusion Passenger you'll need to pass that option
|
843
|
-
when prompted.
|
844
|
-
|
845
|
-
A robust configuration for Apache is possible but tricky; please Google around.
|
846
|
-
(Or help update this Guide if you have a good configuration example for Apache.)
|
847
|
-
|
848
792
|
### Local Precompilation
|
849
793
|
|
850
794
|
There are several reasons why you might want to precompile your assets locally.
|
@@ -1156,7 +1100,7 @@ The following line invokes `uglifier` for JavaScript compression.
|
|
1156
1100
|
config.assets.js_compressor = :uglifier
|
1157
1101
|
```
|
1158
1102
|
|
1159
|
-
NOTE: You will need an [ExecJS](https://github.com/
|
1103
|
+
NOTE: You will need an [ExecJS](https://github.com/rails/execjs#readme)
|
1160
1104
|
supported runtime in order to use `uglifier`. If you are using Mac OS X or
|
1161
1105
|
Windows you have a JavaScript runtime installed in your operating system.
|
1162
1106
|
|
@@ -169,7 +169,7 @@ class CreateCustomers < ActiveRecord::Migration
|
|
169
169
|
end
|
170
170
|
|
171
171
|
create_table :orders do |t|
|
172
|
-
t.belongs_to :customer, index:true
|
172
|
+
t.belongs_to :customer, index: true
|
173
173
|
t.datetime :order_date
|
174
174
|
t.timestamps null: false
|
175
175
|
end
|
@@ -1417,7 +1417,13 @@ The `collection_singular_ids=` method makes the collection contain only the obje
|
|
1417
1417
|
|
1418
1418
|
##### `collection.clear`
|
1419
1419
|
|
1420
|
-
The `collection.clear` method removes
|
1420
|
+
The `collection.clear` method removes all objects from the collection according to the strategy specified by the `dependent` option. If no option is given, it follows the default strategy. The default strategy for `has_many :through` associations is `delete_all`, and for `has_many` associations is to set the foreign keys to `NULL`.
|
1421
|
+
|
1422
|
+
```ruby
|
1423
|
+
@customer.orders.clear
|
1424
|
+
```
|
1425
|
+
|
1426
|
+
WARNING: Objects will be delete if they're associated with `dependent: :destroy`, just like `dependent: :delete_all`.
|
1421
1427
|
|
1422
1428
|
##### `collection.empty?`
|
1423
1429
|
|
@@ -1456,7 +1462,9 @@ The `collection.where` method finds objects within the collection based on the c
|
|
1456
1462
|
|
1457
1463
|
##### `collection.exists?(...)`
|
1458
1464
|
|
1459
|
-
The `collection.exists?` method checks whether an object meeting the supplied
|
1465
|
+
The `collection.exists?` method checks whether an object meeting the supplied
|
1466
|
+
conditions exists in the collection. It uses the same syntax and options as
|
1467
|
+
[`ActiveRecord::Base.exists?`](http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F).
|
1460
1468
|
|
1461
1469
|
##### `collection.build(attributes = {}, ...)`
|
1462
1470
|
|
@@ -1949,7 +1957,9 @@ The `collection.where` method finds objects within the collection based on the c
|
|
1949
1957
|
|
1950
1958
|
##### `collection.exists?(...)`
|
1951
1959
|
|
1952
|
-
The `collection.exists?` method checks whether an object meeting the supplied
|
1960
|
+
The `collection.exists?` method checks whether an object meeting the supplied
|
1961
|
+
conditions exists in the collection. It uses the same syntax and options as
|
1962
|
+
[`ActiveRecord::Base.exists?`](http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F).
|
1953
1963
|
|
1954
1964
|
##### `collection.build(attributes = {})`
|
1955
1965
|
|
@@ -1977,8 +1987,8 @@ While Rails uses intelligent defaults that will work well in most situations, th
|
|
1977
1987
|
|
1978
1988
|
```ruby
|
1979
1989
|
class Parts < ActiveRecord::Base
|
1980
|
-
has_and_belongs_to_many :assemblies,
|
1981
|
-
|
1990
|
+
has_and_belongs_to_many :assemblies, -> { readonly },
|
1991
|
+
autosave: true
|
1982
1992
|
end
|
1983
1993
|
```
|
1984
1994
|
|
@@ -1990,7 +2000,6 @@ The `has_and_belongs_to_many` association supports these options:
|
|
1990
2000
|
* `:foreign_key`
|
1991
2001
|
* `:join_table`
|
1992
2002
|
* `:validate`
|
1993
|
-
* `:readonly`
|
1994
2003
|
|
1995
2004
|
##### `:association_foreign_key`
|
1996
2005
|
|
data/guides/source/{constant_autoloading_and_reloading.md → autoloading_and_reloading_constants.md}
RENAMED
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
Autoloading and Reloading Constants
|
2
|
+
===================================
|
3
3
|
|
4
4
|
This guide documents how constant autoloading and reloading works.
|
5
5
|
|
@@ -78,7 +78,8 @@ end
|
|
78
78
|
```
|
79
79
|
|
80
80
|
The *nesting* at any given place is the collection of enclosing nested class and
|
81
|
-
module objects outwards.
|
81
|
+
module objects outwards. The nesting at any given place can be inspected with
|
82
|
+
`Module.nesting`. For example, in the previous example, the nesting at
|
82
83
|
(1) is
|
83
84
|
|
84
85
|
```ruby
|
@@ -111,6 +112,16 @@ certain nesting does not necessarily correlate with the namespaces at the spot.
|
|
111
112
|
Even more, they are totally independent, take for instance
|
112
113
|
|
113
114
|
```ruby
|
115
|
+
module X
|
116
|
+
module Y
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
module A
|
121
|
+
module B
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
114
125
|
module X::Y
|
115
126
|
module A::B
|
116
127
|
# (3)
|
@@ -138,9 +149,10 @@ executed, and popped after it.
|
|
138
149
|
|
139
150
|
* A singleton class opened with `class << object` gets pushed, and popped later.
|
140
151
|
|
141
|
-
* When
|
152
|
+
* When `instance_eval` is called using a string argument,
|
142
153
|
the singleton class of the receiver is pushed to the nesting of the eval'ed
|
143
|
-
code.
|
154
|
+
code. When `class_eval` or `module_eval` is called using a string argument,
|
155
|
+
the receiver is pushed to the nesting of the eval'ed code.
|
144
156
|
|
145
157
|
* The nesting at the top-level of code interpreted by `Kernel#load` is empty
|
146
158
|
unless the `load` call receives a true value as second argument, in which case
|
@@ -151,8 +163,6 @@ the blocks that may be passed to `Class.new` and `Module.new` do not get the
|
|
151
163
|
class or module being defined pushed to their nesting. That's one of the
|
152
164
|
differences between defining classes and modules in one way or another.
|
153
165
|
|
154
|
-
The nesting at any given place can be inspected with `Module.nesting`.
|
155
|
-
|
156
166
|
### Class and Module Definitions are Constant Assignments
|
157
167
|
|
158
168
|
Let's suppose the following snippet creates a class (rather than reopening it):
|
@@ -186,8 +196,8 @@ Project.name # => "Project"
|
|
186
196
|
```
|
187
197
|
|
188
198
|
Constant assignment has a special rule to make that happen: if the object
|
189
|
-
being assigned is an anonymous class or module, Ruby sets
|
190
|
-
|
199
|
+
being assigned is an anonymous class or module, Ruby sets the object's name to
|
200
|
+
the name of the constant.
|
191
201
|
|
192
202
|
INFO. From then on, what happens to the constant and the instance does not
|
193
203
|
matter. For example, the constant could be deleted, the class object could be
|
@@ -221,7 +231,7 @@ assignment.
|
|
221
231
|
Thus, when one informally says "the `String` class", that really means: the
|
222
232
|
class object stored in the constant called "String" in the class object stored
|
223
233
|
in the `Object` constant. `String` is otherwise an ordinary Ruby constant and
|
224
|
-
everything related to constants
|
234
|
+
everything related to constants such as resolution algorithms applies to it.
|
225
235
|
|
226
236
|
Likewise, in the controller
|
227
237
|
|
@@ -234,7 +244,7 @@ end
|
|
234
244
|
```
|
235
245
|
|
236
246
|
`Post` is not syntax for a class. Rather, `Post` is a regular Ruby constant. If
|
237
|
-
all is good, the constant
|
247
|
+
all is good, the constant is evaluated to an object that responds to `all`.
|
238
248
|
|
239
249
|
That is why we talk about *constant* autoloading, Rails has the ability to
|
240
250
|
load constants on the fly.
|
@@ -256,7 +266,7 @@ module Colors
|
|
256
266
|
end
|
257
267
|
```
|
258
268
|
|
259
|
-
First, when the `module` keyword is processed the interpreter creates a new
|
269
|
+
First, when the `module` keyword is processed, the interpreter creates a new
|
260
270
|
entry in the constant table of the class object stored in the `Object` constant.
|
261
271
|
Said entry associates the name "Colors" to a newly created module object.
|
262
272
|
Furthermore, the interpreter sets the name of the new module object to be the
|
@@ -270,7 +280,7 @@ In particular, `Colors::RED` is totally unrelated to any other `RED` constant
|
|
270
280
|
that may live in any other class or module object. If there were any, they
|
271
281
|
would have separate entries in their respective constant tables.
|
272
282
|
|
273
|
-
|
283
|
+
Pay special attention in the previous paragraphs to the distinction between
|
274
284
|
class and module objects, constant names, and value objects associated to them
|
275
285
|
in constant tables.
|
276
286
|
|
@@ -289,12 +299,14 @@ order. The ancestors of those elements are ignored.
|
|
289
299
|
|
290
300
|
2. If not found, then the algorithm walks up the ancestor chain of the cref.
|
291
301
|
|
292
|
-
3. If not found
|
302
|
+
3. If not found and the cref is a module, the constant is looked up in `Object`.
|
303
|
+
|
304
|
+
4. If not found, `const_missing` is invoked on the cref. The default
|
293
305
|
implementation of `const_missing` raises `NameError`, but it can be overridden.
|
294
306
|
|
295
307
|
Rails autoloading **does not emulate this algorithm**, but its starting point is
|
296
308
|
the name of the constant to be autoloaded, and the cref. See more in [Relative
|
297
|
-
References](#relative-references).
|
309
|
+
References](#autoloading-algorithms-relative-references).
|
298
310
|
|
299
311
|
#### Resolution Algorithm for Qualified Constants
|
300
312
|
|
@@ -312,7 +324,7 @@ relative: `::Billing::Invoice`. That would force `Billing` to be looked up
|
|
312
324
|
only as a top-level constant.
|
313
325
|
|
314
326
|
`Invoice` on the other hand is qualified by `Billing` and we are going to see
|
315
|
-
its resolution next. Let's
|
327
|
+
its resolution next. Let's define *parent* to be that qualifying class or module
|
316
328
|
object, that is, `Billing` in the example above. The algorithm for qualified
|
317
329
|
constants goes like this:
|
318
330
|
|
@@ -328,7 +340,7 @@ checked.
|
|
328
340
|
|
329
341
|
Rails autoloading **does not emulate this algorithm**, but its starting point is
|
330
342
|
the name of the constant to be autoloaded, and the parent. See more in
|
331
|
-
[Qualified References](#qualified-references).
|
343
|
+
[Qualified References](#autoloading-algorithms-qualified-references).
|
332
344
|
|
333
345
|
|
334
346
|
Vocabulary
|
@@ -439,18 +451,19 @@ default it contains:
|
|
439
451
|
`app/controllers`. They do not need to be the default ones, any custom
|
440
452
|
directories like `app/workers` belong automatically to `autoload_paths`.
|
441
453
|
|
442
|
-
*
|
454
|
+
* Second level directories `app/{controllers,models}/concerns` in the
|
443
455
|
application and engines.
|
444
456
|
|
445
457
|
* The directory `test/mailers/previews`.
|
446
458
|
|
447
459
|
Also, this collection is configurable via `config.autoload_paths`. For example,
|
448
460
|
`lib` was in the list years ago, but no longer is. An application can opt-in
|
449
|
-
|
461
|
+
by adding this to `config/application.rb`:
|
450
462
|
|
451
463
|
```ruby
|
452
|
-
config.autoload_paths
|
464
|
+
config.autoload_paths << "#{Rails.root}/lib"
|
453
465
|
```
|
466
|
+
`config.autoload_paths` is accessible from environment-specific configuration files, but any changes made to it outside `config/application.rb` don't have an effect.
|
454
467
|
|
455
468
|
The value of `autoload_paths` can be inspected. In a just generated application
|
456
469
|
it is (edited):
|
@@ -683,12 +696,12 @@ creates an empty module and assigns it to the `Admin` constant on the fly.
|
|
683
696
|
### Generic Procedure
|
684
697
|
|
685
698
|
Relative references are reported to be missing in the cref where they were hit,
|
686
|
-
and qualified references are reported to be missing in their parent
|
699
|
+
and qualified references are reported to be missing in their parent (see
|
687
700
|
[Resolution Algorithm for Relative
|
688
701
|
Constants](#resolution-algorithm-for-relative-constants) at the beginning of
|
689
702
|
this guide for the definition of *cref*, and [Resolution Algorithm for Qualified
|
690
703
|
Constants](#resolution-algorithm-for-qualified-constants) for the definition of
|
691
|
-
*parent
|
704
|
+
*parent*).
|
692
705
|
|
693
706
|
The procedure to autoload constant `C` in an arbitrary situation is as follows:
|
694
707
|
|
@@ -866,8 +879,8 @@ end
|
|
866
879
|
```
|
867
880
|
|
868
881
|
To resolve `User` Ruby checks `Admin` in the former case, but it does not in
|
869
|
-
the latter because it does not belong to the nesting
|
870
|
-
and [Resolution Algorithms](#resolution-algorithms).
|
882
|
+
the latter because it does not belong to the nesting (see [Nesting](#nesting)
|
883
|
+
and [Resolution Algorithms](#resolution-algorithms)).
|
871
884
|
|
872
885
|
Unfortunately Rails autoloading does not know the nesting in the spot where the
|
873
886
|
constant was missing and so it is not able to act as Ruby would. In particular,
|
@@ -889,7 +902,7 @@ end
|
|
889
902
|
|
890
903
|
### Autoloading and STI
|
891
904
|
|
892
|
-
Single Table Inheritance (STI) is a feature of Active Record that
|
905
|
+
Single Table Inheritance (STI) is a feature of Active Record that enables
|
893
906
|
storing a hierarchy of models in one single table. The API of such models is
|
894
907
|
aware of the hierarchy and encapsulates some common needs. For example, given
|
895
908
|
these classes:
|
@@ -1171,7 +1184,8 @@ class Hotel
|
|
1171
1184
|
end
|
1172
1185
|
```
|
1173
1186
|
|
1174
|
-
the expression `Hotel::Image` is ambiguous
|
1187
|
+
the expression `Hotel::Image` is ambiguous because it depends on the execution
|
1188
|
+
path.
|
1175
1189
|
|
1176
1190
|
As [we saw before](#resolution-algorithm-for-qualified-constants), Ruby looks
|
1177
1191
|
up the constant in `Hotel` and its ancestors. If `app/models/image.rb` has
|
@@ -1280,8 +1294,8 @@ c.user # surprisingly fine, User
|
|
1280
1294
|
c.user # NameError: uninitialized constant C::User
|
1281
1295
|
```
|
1282
1296
|
|
1283
|
-
because it detects a parent namespace already has the constant (see [Qualified
|
1284
|
-
References](#qualified-references).
|
1297
|
+
because it detects that a parent namespace already has the constant (see [Qualified
|
1298
|
+
References](#autoloading-algorithms-qualified-references)).
|
1285
1299
|
|
1286
1300
|
As with pure Ruby, within the body of a direct descendant of `BasicObject` use
|
1287
1301
|
always absolute constant paths:
|