rails 4.0.13 → 4.1.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +22 -17
- data/guides/CHANGELOG.md +68 -34
- data/guides/assets/images/edge_badge.png +0 -0
- data/guides/assets/images/feature_tile.gif +0 -0
- data/guides/assets/images/footer_tile.gif +0 -0
- data/guides/assets/images/fxn.png +0 -0
- data/guides/assets/images/getting_started/article_with_comments.png +0 -0
- data/guides/assets/images/getting_started/challenge.png +0 -0
- data/guides/assets/images/getting_started/confirm_dialog.png +0 -0
- data/guides/assets/images/getting_started/forbidden_attributes_for_new_article.png +0 -0
- data/guides/assets/images/getting_started/form_with_errors.png +0 -0
- data/guides/assets/images/getting_started/index_action_with_edit_link.png +0 -0
- data/guides/assets/images/getting_started/new_article.png +0 -0
- data/guides/assets/images/getting_started/rails_welcome.png +0 -0
- data/guides/assets/images/getting_started/routing_error_no_controller.png +0 -0
- data/guides/assets/images/getting_started/routing_error_no_route_matches.png +0 -0
- data/guides/assets/images/getting_started/show_action_for_articles.png +0 -0
- data/guides/assets/images/getting_started/template_is_missing_articles_new.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_create_for_articles.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_new_for_articles.png +0 -0
- data/guides/assets/images/header_tile.gif +0 -0
- data/guides/assets/images/icons/README +1 -1
- data/guides/assets/images/icons/callouts/11.png +0 -0
- data/guides/assets/images/icons/callouts/12.png +0 -0
- data/guides/assets/images/icons/callouts/13.png +0 -0
- data/guides/assets/images/icons/callouts/15.png +0 -0
- data/guides/assets/images/icons/caution.png +0 -0
- data/guides/assets/images/icons/example.png +0 -0
- data/guides/assets/images/radar.png +0 -0
- data/guides/assets/images/rails4_features.png +0 -0
- data/guides/assets/images/rails_guides_kindle_cover.jpg +0 -0
- data/guides/assets/images/vijaydev.jpg +0 -0
- data/guides/assets/javascripts/guides.js +30 -34
- data/guides/assets/stylesheets/main.css +2 -1
- data/guides/assets/stylesheets/print.css +1 -1
- data/guides/bug_report_templates/action_controller_gem.rb +9 -4
- data/guides/bug_report_templates/action_controller_master.rb +4 -2
- data/guides/bug_report_templates/active_record_gem.rb +5 -2
- data/guides/bug_report_templates/active_record_master.rb +2 -1
- data/guides/bug_report_templates/generic_gem.rb +15 -0
- data/guides/bug_report_templates/generic_master.rb +26 -0
- data/guides/code/getting_started/Gemfile +21 -24
- data/guides/code/getting_started/Gemfile.lock +78 -73
- data/guides/code/getting_started/Rakefile +1 -1
- data/guides/code/getting_started/app/assets/javascripts/application.js +1 -2
- data/guides/code/getting_started/app/views/layouts/application.html.erb +2 -2
- data/guides/code/getting_started/config/environment.rb +1 -1
- data/guides/code/getting_started/config/environments/development.rb +2 -2
- data/guides/code/getting_started/config/environments/production.rb +3 -3
- data/guides/code/getting_started/config/environments/test.rb +2 -2
- data/guides/code/getting_started/config/initializers/secret_token.rb +1 -1
- data/guides/code/getting_started/config/initializers/session_store.rb +1 -1
- data/guides/code/getting_started/config/routes.rb +1 -1
- data/guides/code/getting_started/config.ru +1 -1
- data/guides/code/getting_started/public/404.html +2 -0
- data/guides/code/getting_started/public/422.html +2 -0
- data/guides/code/getting_started/public/500.html +2 -0
- data/guides/code/getting_started/test/test_helper.rb +0 -3
- data/guides/rails_guides/helpers.rb +3 -1
- data/guides/source/2_2_release_notes.md +2 -2
- data/guides/source/2_3_release_notes.md +8 -8
- data/guides/source/3_0_release_notes.md +2 -3
- data/guides/source/3_1_release_notes.md +2 -2
- data/guides/source/3_2_release_notes.md +12 -12
- data/guides/source/4_0_release_notes.md +79 -46
- data/guides/source/4_1_release_notes.md +731 -0
- data/guides/source/_welcome.html.erb +5 -2
- data/guides/source/action_controller_overview.md +189 -40
- data/guides/source/action_mailer_basics.md +27 -27
- data/guides/source/action_view_overview.md +131 -20
- data/guides/source/active_model_basics.md +6 -6
- data/guides/source/active_record_basics.md +15 -15
- data/guides/source/active_record_callbacks.md +18 -16
- data/guides/source/active_record_querying.md +93 -51
- data/guides/source/active_record_validations.md +26 -24
- data/guides/source/active_support_core_extensions.md +72 -118
- data/guides/source/active_support_instrumentation.md +13 -4
- data/guides/source/api_documentation_guidelines.md +104 -6
- data/guides/source/asset_pipeline.md +573 -244
- data/guides/source/association_basics.md +94 -22
- data/guides/source/caching_with_rails.md +15 -6
- data/guides/source/command_line.md +55 -46
- data/guides/source/configuring.md +248 -52
- data/guides/source/contributing_to_ruby_on_rails.md +18 -17
- data/guides/source/credits.html.erb +2 -2
- data/guides/source/debugging_rails_applications.md +39 -8
- data/guides/source/development_dependencies_install.md +91 -8
- data/guides/source/documents.yaml +4 -0
- data/guides/source/engines.md +678 -232
- data/guides/source/form_helpers.md +53 -35
- data/guides/source/generators.md +19 -15
- data/guides/source/getting_started.md +758 -497
- data/guides/source/i18n.md +64 -28
- data/guides/source/index.html.erb +1 -1
- data/guides/source/initialization.md +155 -58
- data/guides/source/kindle/toc.html.erb +1 -1
- data/guides/source/layout.html.erb +2 -2
- data/guides/source/layouts_and_rendering.md +59 -26
- data/guides/source/maintenance_policy.md +3 -3
- data/guides/source/migrations.md +101 -62
- data/guides/source/nested_model_forms.md +3 -3
- data/guides/source/plugins.md +34 -31
- data/guides/source/rails_application_templates.md +27 -8
- data/guides/source/rails_on_rack.md +41 -58
- data/guides/source/routing.md +115 -104
- data/guides/source/ruby_on_rails_guides_guidelines.md +2 -2
- data/guides/source/security.md +81 -36
- data/guides/source/testing.md +56 -79
- data/guides/source/upgrading_ruby_on_rails.md +531 -21
- data/guides/source/working_with_javascript_in_rails.md +19 -11
- metadata +51 -23
- data/guides/assets/images/getting_started/forbidden_attributes_for_new_post.png +0 -0
- data/guides/assets/images/getting_started/new_post.png +0 -0
- data/guides/assets/images/getting_started/post_with_comments.png +0 -0
- data/guides/assets/images/getting_started/show_action_for_posts.png +0 -0
- data/guides/assets/images/getting_started/template_is_missing_posts_new.png +0 -0
- data/guides/assets/images/getting_started/undefined_method_post_path.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_create_for_posts.png +0 -0
- data/guides/assets/images/getting_started/unknown_action_new_for_posts.png +0 -0
- data/guides/assets/images/jaimeiniesta.jpg +0 -0
- data/guides/source/kindle/KINDLE.md +0 -26
@@ -37,9 +37,10 @@ For every single method defined as a core extension this guide has a note that s
|
|
37
37
|
|
38
38
|
NOTE: Defined in `active_support/core_ext/object/blank.rb`.
|
39
39
|
|
40
|
-
That means that
|
40
|
+
That means that you can require it like this:
|
41
41
|
|
42
42
|
```ruby
|
43
|
+
require 'active_support'
|
43
44
|
require 'active_support/core_ext/object/blank'
|
44
45
|
```
|
45
46
|
|
@@ -52,6 +53,7 @@ The next level is to simply load all extensions to `Object`. As a rule of thumb,
|
|
52
53
|
Thus, to load all extensions to `Object` (including `blank?`):
|
53
54
|
|
54
55
|
```ruby
|
56
|
+
require 'active_support'
|
55
57
|
require 'active_support/core_ext/object'
|
56
58
|
```
|
57
59
|
|
@@ -60,6 +62,7 @@ require 'active_support/core_ext/object'
|
|
60
62
|
You may prefer just to load all core extensions, there is a file for that:
|
61
63
|
|
62
64
|
```ruby
|
65
|
+
require 'active_support'
|
63
66
|
require 'active_support/core_ext'
|
64
67
|
```
|
65
68
|
|
@@ -96,12 +99,13 @@ INFO: The predicate for strings uses the Unicode-aware character class `[:space:
|
|
96
99
|
|
97
100
|
WARNING: Note that numbers are not mentioned. In particular, 0 and 0.0 are **not** blank.
|
98
101
|
|
99
|
-
For example, this method from `
|
102
|
+
For example, this method from `ActionController::HttpAuthentication::Token::ControllerMethods` uses `blank?` for checking whether a token is present:
|
100
103
|
|
101
104
|
```ruby
|
102
|
-
def
|
103
|
-
|
104
|
-
|
105
|
+
def authenticate(controller, &login_procedure)
|
106
|
+
token, options = token_and_options(controller.request)
|
107
|
+
unless token.blank?
|
108
|
+
login_procedure.call(token, options)
|
105
109
|
end
|
106
110
|
end
|
107
111
|
```
|
@@ -166,7 +170,7 @@ NOTE: Defined in `active_support/core_ext/object/duplicable.rb`.
|
|
166
170
|
|
167
171
|
### `deep_dup`
|
168
172
|
|
169
|
-
The `deep_dup` method returns deep copy of a given object. Normally, when you `dup` an object that contains other objects,
|
173
|
+
The `deep_dup` method returns deep copy of a given object. Normally, when you `dup` an object that contains other objects, Ruby does not `dup` them, so it creates a shallow copy of the object. If you have an array with a string, for example, it will look like this:
|
170
174
|
|
171
175
|
```ruby
|
172
176
|
array = ['string']
|
@@ -175,14 +179,14 @@ duplicate = array.dup
|
|
175
179
|
duplicate.push 'another-string'
|
176
180
|
|
177
181
|
# the object was duplicated, so the element was added only to the duplicate
|
178
|
-
array
|
179
|
-
duplicate
|
182
|
+
array # => ['string']
|
183
|
+
duplicate # => ['string', 'another-string']
|
180
184
|
|
181
185
|
duplicate.first.gsub!('string', 'foo')
|
182
186
|
|
183
187
|
# first element was not duplicated, it will be changed in both arrays
|
184
|
-
array
|
185
|
-
duplicate
|
188
|
+
array # => ['foo']
|
189
|
+
duplicate # => ['foo', 'another-string']
|
186
190
|
```
|
187
191
|
|
188
192
|
As you can see, after duplicating the `Array` instance, we got another object, therefore we can modify it and the original object will stay unchanged. This is not true for array's elements, however. Since `dup` does not make deep copy, the string inside the array is still the same object.
|
@@ -195,8 +199,8 @@ duplicate = array.deep_dup
|
|
195
199
|
|
196
200
|
duplicate.first.gsub!('string', 'foo')
|
197
201
|
|
198
|
-
array
|
199
|
-
duplicate
|
202
|
+
array # => ['string']
|
203
|
+
duplicate # => ['foo']
|
200
204
|
```
|
201
205
|
|
202
206
|
If the object is not duplicable, `deep_dup` will just return it:
|
@@ -420,11 +424,9 @@ NOTE: Defined in `active_support/core_ext/object/with_options.rb`.
|
|
420
424
|
|
421
425
|
### JSON support
|
422
426
|
|
423
|
-
Active Support provides a better
|
427
|
+
Active Support provides a better implementation of `to_json` than the `json` gem ordinarily provides for Ruby objects. This is because some classes, like `Hash`, `OrderedHash` and `Process::Status` need special handling in order to provide a proper JSON representation.
|
424
428
|
|
425
|
-
|
426
|
-
|
427
|
-
NOTE: Defined in `active_support/core_ext/object/to_json.rb`.
|
429
|
+
NOTE: Defined in `active_support/core_ext/object/json.rb`.
|
428
430
|
|
429
431
|
### Instance Variables
|
430
432
|
|
@@ -622,7 +624,7 @@ NOTE: Defined in `active_support/core_ext/module/attr_internal.rb`.
|
|
622
624
|
|
623
625
|
#### Module Attributes
|
624
626
|
|
625
|
-
The macros `mattr_reader`, `mattr_writer`, and `mattr_accessor` are
|
627
|
+
The macros `mattr_reader`, `mattr_writer`, and `mattr_accessor` are the same as the `cattr_*` macros defined for class. In fact, the `cattr_*` macros are just aliases for the `mattr_*` macros. Check [Class Attributes](#class-attributes).
|
626
628
|
|
627
629
|
For example, the dependencies mechanism uses them:
|
628
630
|
|
@@ -733,7 +735,7 @@ X.local_constants # => [:X1, :X2, :Y]
|
|
733
735
|
X::Y.local_constants # => [:Y1, :X1]
|
734
736
|
```
|
735
737
|
|
736
|
-
The names are returned as symbols.
|
738
|
+
The names are returned as symbols.
|
737
739
|
|
738
740
|
NOTE: Defined in `active_support/core_ext/module/introspection.rb`.
|
739
741
|
|
@@ -1062,7 +1064,7 @@ For convenience `class_attribute` also defines an instance predicate which is th
|
|
1062
1064
|
|
1063
1065
|
When `:instance_reader` is `false`, the instance predicate returns a `NoMethodError` just like the reader method.
|
1064
1066
|
|
1065
|
-
If you do not want the instance predicate,
|
1067
|
+
If you do not want the instance predicate, pass `instance_predicate: false` and it will not be defined.
|
1066
1068
|
|
1067
1069
|
NOTE: Defined in `active_support/core_ext/class/attribute.rb`
|
1068
1070
|
|
@@ -1091,6 +1093,15 @@ end
|
|
1091
1093
|
|
1092
1094
|
we can access `field_error_proc` in views.
|
1093
1095
|
|
1096
|
+
Also, you can pass a block to `cattr_*` to set up the attribute with a default value:
|
1097
|
+
|
1098
|
+
```ruby
|
1099
|
+
class MysqlAdapter < AbstractAdapter
|
1100
|
+
# Generates class methods to access @@emulate_booleans with default value of true.
|
1101
|
+
cattr_accessor(:emulate_booleans) { true }
|
1102
|
+
end
|
1103
|
+
```
|
1104
|
+
|
1094
1105
|
The generation of the reader instance method can be prevented by setting `:instance_reader` to `false` and the generation of the writer instance method can be prevented by setting `:instance_writer` to `false`. Generation of both methods can be prevented by setting `:instance_accessor` to `false`. In all cases, the value must be exactly `false` and not any false value.
|
1095
1106
|
|
1096
1107
|
```ruby
|
@@ -1108,7 +1119,7 @@ end
|
|
1108
1119
|
|
1109
1120
|
A model may find it useful to set `:instance_accessor` to `false` as a way to prevent mass-assignment from setting the attribute.
|
1110
1121
|
|
1111
|
-
NOTE: Defined in `active_support/core_ext/
|
1122
|
+
NOTE: Defined in `active_support/core_ext/module/attribute_accessors.rb`.
|
1112
1123
|
|
1113
1124
|
### Subclasses & Descendants
|
1114
1125
|
|
@@ -1248,6 +1259,18 @@ Calling `to_s` on a safe string returns a safe string, but coercion with `to_str
|
|
1248
1259
|
|
1249
1260
|
Calling `dup` or `clone` on safe strings yields safe strings.
|
1250
1261
|
|
1262
|
+
### `remove`
|
1263
|
+
|
1264
|
+
The method `remove` will remove all occurrences of the pattern:
|
1265
|
+
|
1266
|
+
```ruby
|
1267
|
+
"Hello World".remove(/Hello /) => "World"
|
1268
|
+
```
|
1269
|
+
|
1270
|
+
There's also the destructive version `String#remove!`.
|
1271
|
+
|
1272
|
+
NOTE: Defined in `active_support/core_ext/string/filters.rb`.
|
1273
|
+
|
1251
1274
|
### `squish`
|
1252
1275
|
|
1253
1276
|
The method `squish` strips leading and trailing whitespace, and substitutes runs of whitespace with a single space each:
|
@@ -1449,7 +1472,7 @@ The method `pluralize` returns the plural of its receiver:
|
|
1449
1472
|
|
1450
1473
|
As the previous example shows, Active Support knows some irregular plurals and uncountable nouns. Built-in rules can be extended in `config/initializers/inflections.rb`. That file is generated by the `rails` command and has instructions in comments.
|
1451
1474
|
|
1452
|
-
`pluralize` can also take an optional `count` parameter.
|
1475
|
+
`pluralize` can also take an optional `count` parameter. If `count == 1` the singular form will be returned. For any other value of `count` the plural form will be returned:
|
1453
1476
|
|
1454
1477
|
```ruby
|
1455
1478
|
"dude".pluralize(0) # => "dudes"
|
@@ -1533,7 +1556,7 @@ ActiveSupport::Inflector.inflections do |inflect|
|
|
1533
1556
|
inflect.acronym 'SSL'
|
1534
1557
|
end
|
1535
1558
|
|
1536
|
-
"SSLError".underscore.camelize
|
1559
|
+
"SSLError".underscore.camelize # => "SSLError"
|
1537
1560
|
```
|
1538
1561
|
|
1539
1562
|
`camelize` is aliased to `camelcase`.
|
@@ -1763,6 +1786,12 @@ The method `humanize` gives you a sensible name for display out of an attribute
|
|
1763
1786
|
"comments_count".humanize # => "Comments count"
|
1764
1787
|
```
|
1765
1788
|
|
1789
|
+
The capitalization of the first word can be turned off by setting the optional parameter `capitalize` to false:
|
1790
|
+
|
1791
|
+
```ruby
|
1792
|
+
"author_id".humanize(capitalize: false) # => "author"
|
1793
|
+
```
|
1794
|
+
|
1766
1795
|
The helper method `full_messages` uses `humanize` as a fallback to include attribute names:
|
1767
1796
|
|
1768
1797
|
```ruby
|
@@ -1989,7 +2018,7 @@ Produce a string representation of a number in human-readable words:
|
|
1989
2018
|
1234567890123456.to_s(:human) # => "1.23 Quadrillion"
|
1990
2019
|
```
|
1991
2020
|
|
1992
|
-
NOTE: Defined in `active_support/core_ext/numeric/
|
2021
|
+
NOTE: Defined in `active_support/core_ext/numeric/conversions.rb`.
|
1993
2022
|
|
1994
2023
|
Extensions to `Integer`
|
1995
2024
|
-----------------------
|
@@ -2432,7 +2461,7 @@ dup[1][2] = 4
|
|
2432
2461
|
array[1][2] == nil # => true
|
2433
2462
|
```
|
2434
2463
|
|
2435
|
-
NOTE: Defined in `active_support/core_ext/
|
2464
|
+
NOTE: Defined in `active_support/core_ext/object/deep_dup.rb`.
|
2436
2465
|
|
2437
2466
|
### Grouping
|
2438
2467
|
|
@@ -2658,45 +2687,7 @@ hash[:b][:e] == nil # => true
|
|
2658
2687
|
hash[:b][:d] == [3, 4] # => true
|
2659
2688
|
```
|
2660
2689
|
|
2661
|
-
NOTE: Defined in `active_support/core_ext/
|
2662
|
-
|
2663
|
-
### Diffing
|
2664
|
-
|
2665
|
-
The method `diff` returns a hash that represents a diff of the receiver and the argument with the following logic:
|
2666
|
-
|
2667
|
-
* Pairs `key`, `value` that exist in both hashes do not belong to the diff hash.
|
2668
|
-
|
2669
|
-
* If both hashes have `key`, but with different values, the pair in the receiver wins.
|
2670
|
-
|
2671
|
-
* The rest is just merged.
|
2672
|
-
|
2673
|
-
```ruby
|
2674
|
-
{a: 1}.diff(a: 1)
|
2675
|
-
# => {}, first rule
|
2676
|
-
|
2677
|
-
{a: 1}.diff(a: 2)
|
2678
|
-
# => {:a=>1}, second rule
|
2679
|
-
|
2680
|
-
{a: 1}.diff(b: 2)
|
2681
|
-
# => {:a=>1, :b=>2}, third rule
|
2682
|
-
|
2683
|
-
{a: 1, b: 2, c: 3}.diff(b: 1, c: 3, d: 4)
|
2684
|
-
# => {:a=>1, :b=>2, :d=>4}, all rules
|
2685
|
-
|
2686
|
-
{}.diff({}) # => {}
|
2687
|
-
{a: 1}.diff({}) # => {:a=>1}
|
2688
|
-
{}.diff(a: 1) # => {:a=>1}
|
2689
|
-
```
|
2690
|
-
|
2691
|
-
An important property of this diff hash is that you can retrieve the original hash by applying `diff` twice:
|
2692
|
-
|
2693
|
-
```ruby
|
2694
|
-
hash.diff(hash2).diff(hash2) == hash
|
2695
|
-
```
|
2696
|
-
|
2697
|
-
Diffing hashes may be useful for error messages related to expected option hashes for example.
|
2698
|
-
|
2699
|
-
NOTE: Defined in `active_support/core_ext/hash/diff.rb`.
|
2690
|
+
NOTE: Defined in `active_support/core_ext/object/deep_dup.rb`.
|
2700
2691
|
|
2701
2692
|
### Working with Keys
|
2702
2693
|
|
@@ -2724,14 +2715,14 @@ NOTE: Defined in `active_support/core_ext/hash/except.rb`.
|
|
2724
2715
|
The method `transform_keys` accepts a block and returns a hash that has applied the block operations to each of the keys in the receiver:
|
2725
2716
|
|
2726
2717
|
```ruby
|
2727
|
-
{nil => nil, 1 => 1, a: :a}.transform_keys{ |key| key.to_s.upcase }
|
2718
|
+
{nil => nil, 1 => 1, a: :a}.transform_keys { |key| key.to_s.upcase }
|
2728
2719
|
# => {"" => nil, "A" => :a, "1" => 1}
|
2729
2720
|
```
|
2730
2721
|
|
2731
2722
|
The result in case of collision is undefined:
|
2732
2723
|
|
2733
2724
|
```ruby
|
2734
|
-
{"a" => 1, a: 2}.transform_keys{ |key| key.to_s.upcase }
|
2725
|
+
{"a" => 1, a: 2}.transform_keys { |key| key.to_s.upcase }
|
2735
2726
|
# => {"A" => 2}, in my test, can't rely on this result though
|
2736
2727
|
```
|
2737
2728
|
|
@@ -2739,11 +2730,11 @@ This method may be useful for example to build specialized conversions. For inst
|
|
2739
2730
|
|
2740
2731
|
```ruby
|
2741
2732
|
def stringify_keys
|
2742
|
-
transform_keys{ |key| key.to_s }
|
2733
|
+
transform_keys { |key| key.to_s }
|
2743
2734
|
end
|
2744
2735
|
...
|
2745
2736
|
def symbolize_keys
|
2746
|
-
transform_keys{ |key| key.to_sym rescue key }
|
2737
|
+
transform_keys { |key| key.to_sym rescue key }
|
2747
2738
|
end
|
2748
2739
|
```
|
2749
2740
|
|
@@ -2752,7 +2743,7 @@ There's also the bang variant `transform_keys!` that applies the block operation
|
|
2752
2743
|
Besides that, one can use `deep_transform_keys` and `deep_transform_keys!` to perform the block operation on all the keys in the given hash and all the hashes nested into it. An example of the result is:
|
2753
2744
|
|
2754
2745
|
```ruby
|
2755
|
-
{nil => nil, 1 => 1, nested: {a: 3, 5 => 5}}.deep_transform_keys{ |key| key.to_s.upcase }
|
2746
|
+
{nil => nil, 1 => 1, nested: {a: 3, 5 => 5}}.deep_transform_keys { |key| key.to_s.upcase }
|
2756
2747
|
# => {""=>nil, "1"=>1, "NESTED"=>{"A"=>3, "5"=>5}}
|
2757
2748
|
```
|
2758
2749
|
|
@@ -2918,6 +2909,16 @@ The method `with_indifferent_access` returns an `ActiveSupport::HashWithIndiffer
|
|
2918
2909
|
|
2919
2910
|
NOTE: Defined in `active_support/core_ext/hash/indifferent_access.rb`.
|
2920
2911
|
|
2912
|
+
### Compacting
|
2913
|
+
|
2914
|
+
The methods `compact` and `compact!` return a Hash without items with `nil` value.
|
2915
|
+
|
2916
|
+
```ruby
|
2917
|
+
{a: 1, b: 2, c: nil}.compact # => {a: 1, b: 2}
|
2918
|
+
```
|
2919
|
+
|
2920
|
+
NOTE: Defined in `active_support/core_ext/hash/compact.rb`.
|
2921
|
+
|
2921
2922
|
Extensions to `Regexp`
|
2922
2923
|
----------------------
|
2923
2924
|
|
@@ -3002,53 +3003,6 @@ The method `Range#overlaps?` says whether any two given ranges have non-void int
|
|
3002
3003
|
|
3003
3004
|
NOTE: Defined in `active_support/core_ext/range/overlaps.rb`.
|
3004
3005
|
|
3005
|
-
Extensions to `Proc`
|
3006
|
-
--------------------
|
3007
|
-
|
3008
|
-
### `bind`
|
3009
|
-
|
3010
|
-
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:
|
3011
|
-
|
3012
|
-
```ruby
|
3013
|
-
Hash.instance_method(:delete) # => #<UnboundMethod: Hash#delete>
|
3014
|
-
```
|
3015
|
-
|
3016
|
-
An unbound method is not callable as is, you need to bind it first to an object with `bind`:
|
3017
|
-
|
3018
|
-
```ruby
|
3019
|
-
clear = Hash.instance_method(:clear)
|
3020
|
-
clear.bind({a: 1}).call # => {}
|
3021
|
-
```
|
3022
|
-
|
3023
|
-
Active Support defines `Proc#bind` with an analogous purpose:
|
3024
|
-
|
3025
|
-
```ruby
|
3026
|
-
Proc.new { size }.bind([]).call # => 0
|
3027
|
-
```
|
3028
|
-
|
3029
|
-
As you see that's callable and bound to the argument, the return value is indeed a `Method`.
|
3030
|
-
|
3031
|
-
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.
|
3032
|
-
|
3033
|
-
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:
|
3034
|
-
|
3035
|
-
```ruby
|
3036
|
-
def handler_for_rescue(exception)
|
3037
|
-
_, rescuer = Array(rescue_handlers).reverse.detect do |klass_name, handler|
|
3038
|
-
...
|
3039
|
-
end
|
3040
|
-
|
3041
|
-
case rescuer
|
3042
|
-
when Symbol
|
3043
|
-
method(rescuer)
|
3044
|
-
when Proc
|
3045
|
-
rescuer.bind(self)
|
3046
|
-
end
|
3047
|
-
end
|
3048
|
-
```
|
3049
|
-
|
3050
|
-
NOTE: Defined in `active_support/core_ext/proc.rb`.
|
3051
|
-
|
3052
3006
|
Extensions to `Date`
|
3053
3007
|
--------------------
|
3054
3008
|
|
@@ -3831,13 +3785,13 @@ def default_helper_module!
|
|
3831
3785
|
module_path = module_name.underscore
|
3832
3786
|
helper module_path
|
3833
3787
|
rescue MissingSourceFile => e
|
3834
|
-
raise e unless e.is_missing? "
|
3788
|
+
raise e unless e.is_missing? "helpers/#{module_path}_helper"
|
3835
3789
|
rescue NameError => e
|
3836
3790
|
raise e unless e.missing_name? "#{module_name}Helper"
|
3837
3791
|
end
|
3838
3792
|
```
|
3839
3793
|
|
3840
|
-
NOTE: Defined in `
|
3794
|
+
NOTE: Defined in `actionpack/lib/abstract_controller/helpers.rb`.
|
3841
3795
|
|
3842
3796
|
Extensions to `LoadError`
|
3843
3797
|
-------------------------
|
@@ -3860,4 +3814,4 @@ rescue NameError => e
|
|
3860
3814
|
end
|
3861
3815
|
```
|
3862
3816
|
|
3863
|
-
NOTE: Defined in `
|
3817
|
+
NOTE: Defined in `actionpack/lib/abstract_controller/helpers.rb`.
|
@@ -39,7 +39,7 @@ Action Controller
|
|
39
39
|
|
40
40
|
```ruby
|
41
41
|
{
|
42
|
-
key: 'posts/1-
|
42
|
+
key: 'posts/1-dashboard-view'
|
43
43
|
}
|
44
44
|
```
|
45
45
|
|
@@ -51,7 +51,7 @@ Action Controller
|
|
51
51
|
|
52
52
|
```ruby
|
53
53
|
{
|
54
|
-
key: 'posts/1-
|
54
|
+
key: 'posts/1-dashboard-view'
|
55
55
|
}
|
56
56
|
```
|
57
57
|
|
@@ -63,7 +63,7 @@ Action Controller
|
|
63
63
|
|
64
64
|
```ruby
|
65
65
|
{
|
66
|
-
key: 'posts/1-
|
66
|
+
key: 'posts/1-dashboard-view'
|
67
67
|
}
|
68
68
|
```
|
69
69
|
|
@@ -75,7 +75,7 @@ Action Controller
|
|
75
75
|
|
76
76
|
```ruby
|
77
77
|
{
|
78
|
-
key: 'posts/1-
|
78
|
+
key: 'posts/1-dashboard-view'
|
79
79
|
}
|
80
80
|
```
|
81
81
|
|
@@ -396,6 +396,15 @@ INFO. Cache stores my add their own keys
|
|
396
396
|
}
|
397
397
|
```
|
398
398
|
|
399
|
+
Railties
|
400
|
+
--------
|
401
|
+
|
402
|
+
### load_config_initializer.railties
|
403
|
+
|
404
|
+
| Key | Value |
|
405
|
+
| -------------- | ----------------------------------------------------- |
|
406
|
+
| `:initializer` | Path to loaded initializer from `config/initializers` |
|
407
|
+
|
399
408
|
Rails
|
400
409
|
-----
|
401
410
|
|
@@ -25,7 +25,7 @@ Write in present tense: "Returns a hash that...", rather than "Returned a hash t
|
|
25
25
|
Start comments in upper case. Follow regular punctuation rules:
|
26
26
|
|
27
27
|
```ruby
|
28
|
-
# Declares an attribute reader backed by an internally-named
|
28
|
+
# Declares an attribute reader backed by an internally-named
|
29
29
|
# instance variable.
|
30
30
|
def attr_internal_reader(*attrs)
|
31
31
|
...
|
@@ -42,7 +42,21 @@ Spell names correctly: Arel, Test::Unit, RSpec, HTML, MySQL, JavaScript, ERB. Wh
|
|
42
42
|
|
43
43
|
Use the article "an" for "SQL", as in "an SQL statement". Also "an SQLite database".
|
44
44
|
|
45
|
-
|
45
|
+
Prefer wordings that avoid "you"s and "your"s. For example, instead of
|
46
|
+
|
47
|
+
```markdown
|
48
|
+
If you need to use `return` statements in your callbacks, it is recommended that you explicitly define them as methods.
|
49
|
+
```
|
50
|
+
|
51
|
+
use this style:
|
52
|
+
|
53
|
+
```markdown
|
54
|
+
If `return` is needed it is recommended to explicitly define a method.
|
55
|
+
```
|
56
|
+
|
57
|
+
That said, when using pronouns in reference to a hypothetical person, such as "a
|
58
|
+
user with a session cookie", gender neutral pronouns (they/their/them) should be
|
59
|
+
used. Instead of:
|
46
60
|
|
47
61
|
* he or she... use they.
|
48
62
|
* him or her... use them.
|
@@ -53,7 +67,7 @@ When using pronouns in reference to a hypothetical person, such as "a user with
|
|
53
67
|
English
|
54
68
|
-------
|
55
69
|
|
56
|
-
Please use American English (<em>color</em>, <em>center</em>, <em>modularize</em>, etc)
|
70
|
+
Please use American English (<em>color</em>, <em>center</em>, <em>modularize</em>, etc). See [a list of American and British English spelling differences here](http://en.wikipedia.org/wiki/American_and_British_English_spelling_differences).
|
57
71
|
|
58
72
|
Example Code
|
59
73
|
------------
|
@@ -65,7 +79,7 @@ Use two spaces to indent chunks of code--that is, for markup purposes, two space
|
|
65
79
|
Short docs do not need an explicit "Examples" label to introduce snippets; they just follow paragraphs:
|
66
80
|
|
67
81
|
```ruby
|
68
|
-
# Converts a collection of elements into a formatted string by
|
82
|
+
# Converts a collection of elements into a formatted string by
|
69
83
|
# calling +to_s+ on all elements and joining them.
|
70
84
|
#
|
71
85
|
# Blog.all.to_formatted_s # => "First PostSecond PostThird Post"
|
@@ -114,6 +128,53 @@ On the other hand, regular comments do not use an arrow:
|
|
114
128
|
# polymorphic_url(record) # same as comment_url(record)
|
115
129
|
```
|
116
130
|
|
131
|
+
Booleans
|
132
|
+
--------
|
133
|
+
|
134
|
+
In predicates and flags prefer documenting boolean semantics over exact values.
|
135
|
+
|
136
|
+
When "true" or "false" are used as defined in Ruby use regular font. The
|
137
|
+
singletons `true` and `false` need fixed-width font. Please avoid terms like
|
138
|
+
"truthy", Ruby defines what is true and false in the language, and thus those
|
139
|
+
words have a technical meaning and need no substitutes.
|
140
|
+
|
141
|
+
As a rule of thumb, do not document singletons unless absolutely necessary. That
|
142
|
+
prevents artificial constructs like `!!` or ternaries, allows refactors, and the
|
143
|
+
code does not need to rely on the exact values returned by methods being called
|
144
|
+
in the implementation.
|
145
|
+
|
146
|
+
For example:
|
147
|
+
|
148
|
+
```markdown
|
149
|
+
`config.action_mailer.perform_deliveries` specifies whether mail will actually be delivered and is true by default
|
150
|
+
```
|
151
|
+
|
152
|
+
the user does not need to know which is the actual default value of the flag,
|
153
|
+
and so we only document its boolean semantics.
|
154
|
+
|
155
|
+
An example with a predicate:
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
# Returns true if the collection is empty.
|
159
|
+
#
|
160
|
+
# If the collection has been loaded
|
161
|
+
# it is equivalent to <tt>collection.size.zero?</tt>. If the
|
162
|
+
# collection has not been loaded, it is equivalent to
|
163
|
+
# <tt>collection.exists?</tt>. If the collection has not already been
|
164
|
+
# loaded and you are going to fetch the records anyway it is better to
|
165
|
+
# check <tt>collection.length.zero?</tt>.
|
166
|
+
def empty?
|
167
|
+
if loaded?
|
168
|
+
size.zero?
|
169
|
+
else
|
170
|
+
@target.blank? && !scope.exists?
|
171
|
+
end
|
172
|
+
end
|
173
|
+
```
|
174
|
+
|
175
|
+
The API is careful not to commit to any particular value, the method has
|
176
|
+
predicate semantics, that's enough.
|
177
|
+
|
117
178
|
Filenames
|
118
179
|
---------
|
119
180
|
|
@@ -149,7 +210,10 @@ class Array
|
|
149
210
|
end
|
150
211
|
```
|
151
212
|
|
152
|
-
WARNING: Using
|
213
|
+
WARNING: Using `+...+` for fixed-width font only works with simple content like
|
214
|
+
ordinary method names, symbols, paths (with forward slashes), etc. Please use
|
215
|
+
`<tt>...</tt>` for everything else, notably class or module names with a
|
216
|
+
namespace as in `<tt>ActiveRecord::Base</tt>`.
|
153
217
|
|
154
218
|
### Regular Font
|
155
219
|
|
@@ -180,7 +244,7 @@ In lists of options, parameters, etc. use a hyphen between the item and its desc
|
|
180
244
|
# * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
|
181
245
|
```
|
182
246
|
|
183
|
-
The description starts in upper case and ends with a full stop
|
247
|
+
The description starts in upper case and ends with a full stop-it's standard English.
|
184
248
|
|
185
249
|
Dynamically Generated Methods
|
186
250
|
-----------------------------
|
@@ -215,3 +279,37 @@ self.class_eval %{
|
|
215
279
|
end
|
216
280
|
}
|
217
281
|
```
|
282
|
+
|
283
|
+
Method Visibility
|
284
|
+
-----------------
|
285
|
+
|
286
|
+
When writing documentation for Rails, it's important to understand the difference between public API (or User-facing) vs. internal API.
|
287
|
+
|
288
|
+
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
|
+
|
290
|
+
This means that there are methods in Rails with `public` visibility that aren't meant for user consumption.
|
291
|
+
|
292
|
+
An example of this is `ActiveRecord::Core::ClassMethods#arel_table`:
|
293
|
+
|
294
|
+
```ruby
|
295
|
+
module ActiveRecord::Core::ClassMethods
|
296
|
+
def arel_table #:nodoc:
|
297
|
+
# do some magic..
|
298
|
+
end
|
299
|
+
end
|
300
|
+
```
|
301
|
+
|
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 plugin or application. Otherwise, you risk your app or gem breaking when you upgrade to a newer release of Rails.
|
303
|
+
|
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, which takes an eternity. 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 from private later, but changing public API is much harder due to backwards compatibility.
|
305
|
+
|
306
|
+
A class or module is marked with `:nodoc:` to indicate that all methods are internal API and should never be used directly.
|
307
|
+
|
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 Pull Request process instead of the docrails project.
|
309
|
+
|
310
|
+
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
|
+
|
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 Pull Request first.
|
313
|
+
|
314
|
+
For whatever reason, 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).
|
315
|
+
|