rails 4.1.16 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -10
  3. data/guides/CHANGELOG.md +15 -100
  4. data/guides/Rakefile +5 -3
  5. data/guides/assets/javascripts/guides.js +6 -0
  6. data/guides/assets/stylesheets/main.css +4 -1
  7. data/guides/bug_report_templates/action_controller_master.rb +1 -0
  8. data/guides/rails_guides/helpers.rb +1 -1
  9. data/guides/rails_guides/levenshtein.rb +29 -21
  10. data/guides/rails_guides/markdown/renderer.rb +1 -1
  11. data/guides/rails_guides/markdown.rb +11 -7
  12. data/guides/rails_guides.rb +2 -2
  13. data/guides/source/2_2_release_notes.md +1 -1
  14. data/guides/source/2_3_release_notes.md +4 -4
  15. data/guides/source/3_0_release_notes.md +8 -8
  16. data/guides/source/3_1_release_notes.md +6 -3
  17. data/guides/source/3_2_release_notes.md +6 -3
  18. data/guides/source/4_0_release_notes.md +6 -3
  19. data/guides/source/4_1_release_notes.md +5 -6
  20. data/guides/source/4_2_release_notes.md +850 -0
  21. data/guides/source/_license.html.erb +1 -1
  22. data/guides/source/_welcome.html.erb +2 -8
  23. data/guides/source/action_controller_overview.md +81 -7
  24. data/guides/source/action_mailer_basics.md +91 -28
  25. data/guides/source/action_view_overview.md +148 -130
  26. data/guides/source/active_job_basics.md +318 -0
  27. data/guides/source/active_model_basics.md +371 -17
  28. data/guides/source/active_record_basics.md +19 -18
  29. data/guides/source/active_record_callbacks.md +12 -9
  30. data/guides/source/{migrations.md → active_record_migrations.md} +95 -220
  31. data/guides/source/active_record_postgresql.md +433 -0
  32. data/guides/source/active_record_querying.md +263 -265
  33. data/guides/source/active_record_validations.md +20 -11
  34. data/guides/source/active_support_core_extensions.md +159 -72
  35. data/guides/source/active_support_instrumentation.md +10 -7
  36. data/guides/source/api_documentation_guidelines.md +62 -16
  37. data/guides/source/asset_pipeline.md +258 -63
  38. data/guides/source/association_basics.md +81 -74
  39. data/guides/source/caching_with_rails.md +32 -7
  40. data/guides/source/command_line.md +52 -30
  41. data/guides/source/configuring.md +132 -29
  42. data/guides/source/constant_autoloading_and_reloading.md +1297 -0
  43. data/guides/source/contributing_to_ruby_on_rails.md +192 -112
  44. data/guides/source/credits.html.erb +2 -2
  45. data/guides/source/debugging_rails_applications.md +440 -286
  46. data/guides/source/development_dependencies_install.md +47 -36
  47. data/guides/source/documents.yaml +19 -7
  48. data/guides/source/engines.md +182 -182
  49. data/guides/source/form_helpers.md +79 -56
  50. data/guides/source/generators.md +24 -11
  51. data/guides/source/getting_started.md +337 -198
  52. data/guides/source/i18n.md +108 -65
  53. data/guides/source/index.html.erb +1 -0
  54. data/guides/source/initialization.md +108 -61
  55. data/guides/source/layout.html.erb +1 -4
  56. data/guides/source/layouts_and_rendering.md +27 -25
  57. data/guides/source/maintenance_policy.md +6 -3
  58. data/guides/source/nested_model_forms.md +7 -4
  59. data/guides/source/plugins.md +27 -27
  60. data/guides/source/rails_application_templates.md +21 -3
  61. data/guides/source/rails_on_rack.md +8 -4
  62. data/guides/source/routing.md +98 -72
  63. data/guides/source/ruby_on_rails_guides_guidelines.md +11 -12
  64. data/guides/source/security.md +38 -32
  65. data/guides/source/testing.md +188 -117
  66. data/guides/source/upgrading_ruby_on_rails.md +254 -28
  67. data/guides/source/working_with_javascript_in_rails.md +18 -16
  68. data/guides/w3c_validator.rb +2 -0
  69. metadata +40 -96
  70. data/guides/bug_report_templates/generic_gem.rb +0 -15
  71. data/guides/bug_report_templates/generic_master.rb +0 -26
  72. data/guides/code/getting_started/Gemfile +0 -40
  73. data/guides/code/getting_started/Gemfile.lock +0 -125
  74. data/guides/code/getting_started/README.rdoc +0 -28
  75. data/guides/code/getting_started/Rakefile +0 -6
  76. data/guides/code/getting_started/app/assets/javascripts/application.js +0 -15
  77. data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +0 -3
  78. data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +0 -3
  79. data/guides/code/getting_started/app/assets/javascripts/welcome.js.coffee +0 -3
  80. data/guides/code/getting_started/app/assets/stylesheets/application.css +0 -13
  81. data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +0 -3
  82. data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +0 -3
  83. data/guides/code/getting_started/app/assets/stylesheets/welcome.css.scss +0 -3
  84. data/guides/code/getting_started/app/controllers/application_controller.rb +0 -5
  85. data/guides/code/getting_started/app/controllers/comments_controller.rb +0 -23
  86. data/guides/code/getting_started/app/controllers/posts_controller.rb +0 -53
  87. data/guides/code/getting_started/app/controllers/welcome_controller.rb +0 -4
  88. data/guides/code/getting_started/app/helpers/application_helper.rb +0 -2
  89. data/guides/code/getting_started/app/helpers/comments_helper.rb +0 -2
  90. data/guides/code/getting_started/app/helpers/posts_helper.rb +0 -2
  91. data/guides/code/getting_started/app/helpers/welcome_helper.rb +0 -2
  92. data/guides/code/getting_started/app/models/comment.rb +0 -3
  93. data/guides/code/getting_started/app/models/post.rb +0 -7
  94. data/guides/code/getting_started/app/views/comments/_comment.html.erb +0 -15
  95. data/guides/code/getting_started/app/views/comments/_form.html.erb +0 -13
  96. data/guides/code/getting_started/app/views/layouts/application.html.erb +0 -14
  97. data/guides/code/getting_started/app/views/posts/_form.html.erb +0 -27
  98. data/guides/code/getting_started/app/views/posts/edit.html.erb +0 -5
  99. data/guides/code/getting_started/app/views/posts/index.html.erb +0 -21
  100. data/guides/code/getting_started/app/views/posts/new.html.erb +0 -5
  101. data/guides/code/getting_started/app/views/posts/show.html.erb +0 -18
  102. data/guides/code/getting_started/app/views/welcome/index.html.erb +0 -4
  103. data/guides/code/getting_started/bin/bundle +0 -4
  104. data/guides/code/getting_started/bin/rails +0 -4
  105. data/guides/code/getting_started/bin/rake +0 -4
  106. data/guides/code/getting_started/config/application.rb +0 -18
  107. data/guides/code/getting_started/config/boot.rb +0 -4
  108. data/guides/code/getting_started/config/database.yml +0 -25
  109. data/guides/code/getting_started/config/environment.rb +0 -5
  110. data/guides/code/getting_started/config/environments/development.rb +0 -30
  111. data/guides/code/getting_started/config/environments/production.rb +0 -80
  112. data/guides/code/getting_started/config/environments/test.rb +0 -36
  113. data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +0 -7
  114. data/guides/code/getting_started/config/initializers/filter_parameter_logging.rb +0 -4
  115. data/guides/code/getting_started/config/initializers/inflections.rb +0 -16
  116. data/guides/code/getting_started/config/initializers/locale.rb +0 -9
  117. data/guides/code/getting_started/config/initializers/mime_types.rb +0 -5
  118. data/guides/code/getting_started/config/initializers/secret_token.rb +0 -12
  119. data/guides/code/getting_started/config/initializers/session_store.rb +0 -3
  120. data/guides/code/getting_started/config/initializers/wrap_parameters.rb +0 -14
  121. data/guides/code/getting_started/config/locales/en.yml +0 -23
  122. data/guides/code/getting_started/config/routes.rb +0 -7
  123. data/guides/code/getting_started/config.ru +0 -4
  124. data/guides/code/getting_started/db/migrate/20130122042648_create_posts.rb +0 -10
  125. data/guides/code/getting_started/db/migrate/20130122045842_create_comments.rb +0 -11
  126. data/guides/code/getting_started/db/schema.rb +0 -33
  127. data/guides/code/getting_started/db/seeds.rb +0 -7
  128. data/guides/code/getting_started/public/404.html +0 -60
  129. data/guides/code/getting_started/public/422.html +0 -60
  130. data/guides/code/getting_started/public/500.html +0 -59
  131. data/guides/code/getting_started/public/favicon.ico +0 -0
  132. data/guides/code/getting_started/public/robots.txt +0 -5
  133. data/guides/code/getting_started/test/controllers/comments_controller_test.rb +0 -7
  134. data/guides/code/getting_started/test/controllers/posts_controller_test.rb +0 -7
  135. data/guides/code/getting_started/test/controllers/welcome_controller_test.rb +0 -9
  136. data/guides/code/getting_started/test/fixtures/comments.yml +0 -11
  137. data/guides/code/getting_started/test/fixtures/posts.yml +0 -9
  138. data/guides/code/getting_started/test/helpers/comments_helper_test.rb +0 -4
  139. data/guides/code/getting_started/test/helpers/posts_helper_test.rb +0 -4
  140. data/guides/code/getting_started/test/helpers/welcome_helper_test.rb +0 -4
  141. data/guides/code/getting_started/test/models/comment_test.rb +0 -7
  142. data/guides/code/getting_started/test/models/post_test.rb +0 -7
  143. data/guides/code/getting_started/test/test_helper.rb +0 -12
@@ -361,6 +361,8 @@ class Product < ActiveRecord::Base
361
361
  end
362
362
  ```
363
363
 
364
+ Alternatively, you can require that the specified attribute does _not_ match the regular expression by using the `:without` option.
365
+
364
366
  The default error message is _"is invalid"_.
365
367
 
366
368
  ### `inclusion`
@@ -425,7 +427,7 @@ class Essay < ActiveRecord::Base
425
427
  validates :content, length: {
426
428
  minimum: 300,
427
429
  maximum: 400,
428
- tokenizer: lambda { |str| str.scan(/\w+/) },
430
+ tokenizer: lambda { |str| str.split(/\s+/) },
429
431
  too_short: "must have at least %{count} words",
430
432
  too_long: "must have at most %{count} words"
431
433
  }
@@ -524,9 +526,16 @@ If you validate the presence of an object associated via a `has_one` or
524
526
  `marked_for_destruction?`.
525
527
 
526
528
  Since `false.blank?` is true, if you want to validate the presence of a boolean
527
- field you should use `validates :field_name, inclusion: { in: [true, false] }`.
529
+ field you should use one of the following validations:
530
+
531
+ ```ruby
532
+ validates :boolean_field_name, presence: true
533
+ validates :boolean_field_name, inclusion: { in: [true, false] }
534
+ validates :boolean_field_name, exclusion: { in: [nil] }
535
+ ```
528
536
 
529
- The default error message is _"can't be blank"_.
537
+ By using one of these validations, you will ensure the value will NOT be `nil`
538
+ which would result in a `NULL` value in most cases.
530
539
 
531
540
  ### `absence`
532
541
 
@@ -698,7 +707,7 @@ we don't want names and surnames to begin with lower case.
698
707
  ```ruby
699
708
  class Person < ActiveRecord::Base
700
709
  validates_each :name, :surname do |record, attr, value|
701
- record.errors.add(attr, 'must start with upper case') if value =~ /\A[a-z]/
710
+ record.errors.add(attr, 'must start with upper case') if value =~ /\A[[:lower:]]/
702
711
  end
703
712
  end
704
713
  ```
@@ -910,8 +919,8 @@ end
910
919
  The easiest way to add custom validators for validating individual attributes
911
920
  is with the convenient `ActiveModel::EachValidator`. In this case, the custom
912
921
  validator class must implement a `validate_each` method which takes three
913
- arguments: record, attribute and value which correspond to the instance, the
914
- attribute to be validated and the value of the attribute in the passed
922
+ arguments: record, attribute, and value. These correspond to the instance, the
923
+ attribute to be validated, and the value of the attribute in the passed
915
924
  instance.
916
925
 
917
926
  ```ruby
@@ -1129,15 +1138,15 @@ generating a scaffold, Rails will put some ERB into the `_form.html.erb` that
1129
1138
  it generates that displays the full list of errors on that model.
1130
1139
 
1131
1140
  Assuming we have a model that's been saved in an instance variable named
1132
- `@post`, it looks like this:
1141
+ `@article`, it looks like this:
1133
1142
 
1134
1143
  ```ruby
1135
- <% if @post.errors.any? %>
1144
+ <% if @article.errors.any? %>
1136
1145
  <div id="error_explanation">
1137
- <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>
1146
+ <h2><%= pluralize(@article.errors.count, "error") %> prohibited this article from being saved:</h2>
1138
1147
 
1139
1148
  <ul>
1140
- <% @post.errors.full_messages.each do |msg| %>
1149
+ <% @article.errors.full_messages.each do |msg| %>
1141
1150
  <li><%= msg %></li>
1142
1151
  <% end %>
1143
1152
  </ul>
@@ -1151,7 +1160,7 @@ the entry.
1151
1160
 
1152
1161
  ```
1153
1162
  <div class="field_with_errors">
1154
- <input id="post_title" name="post[title]" size="30" type="text" value="">
1163
+ <input id="article_title" name="article[title]" size="30" type="text" value="">
1155
1164
  </div>
1156
1165
  ```
1157
1166
 
@@ -157,12 +157,12 @@ Active Support provides `duplicable?` to programmatically query an object about
157
157
 
158
158
  ```ruby
159
159
  "foo".duplicable? # => true
160
- "".duplicable? # => true
160
+ "".duplicable? # => true
161
161
  0.0.duplicable? # => false
162
- false.duplicable? # => false
162
+ false.duplicable? # => false
163
163
  ```
164
164
 
165
- By definition all objects are `duplicable?` except `nil`, `false`, `true`, symbols, numbers, class, and module objects.
165
+ By definition all objects are `duplicable?` except `nil`, `false`, `true`, symbols, numbers, class, module, and method objects.
166
166
 
167
167
  WARNING: Any class can disallow duplication by removing `dup` and `clone` or raising exceptions from them. Thus only `rescue` can tell whether a given arbitrary object is duplicable. `duplicable?` depends on the hard-coded list above, but it is much faster than `rescue`. Use it only if you know the hard-coded list is enough in your use case.
168
168
 
@@ -572,12 +572,12 @@ NOTE: Defined in `active_support/core_ext/module/aliasing.rb`.
572
572
 
573
573
  #### `alias_attribute`
574
574
 
575
- Model attributes have a reader, a writer, and a predicate. You can alias a model attribute having the corresponding three methods defined for you in one shot. As in other aliasing methods, the new name is the first argument, and the old name is the second (my mnemonic is they go in the same order as if you did an assignment):
575
+ Model attributes have a reader, a writer, and a predicate. You can alias a model attribute having the corresponding three methods defined for you in one shot. As in other aliasing methods, the new name is the first argument, and the old name is the second (one mnemonic is that they go in the same order as if you did an assignment):
576
576
 
577
577
  ```ruby
578
578
  class User < ActiveRecord::Base
579
- # let me refer to the email column as "login",
580
- # possibly meaningful for authentication code
579
+ # You can refer to the email column as "login".
580
+ # This can be meaningful for authentication code.
581
581
  alias_attribute :login, :email
582
582
  end
583
583
  ```
@@ -761,7 +761,7 @@ Arguments may be bare constant names:
761
761
  Math.qualified_const_get("E") # => 2.718281828459045
762
762
  ```
763
763
 
764
- These methods are analogous to their builtin counterparts. In particular,
764
+ These methods are analogous to their built-in counterparts. In particular,
765
765
  `qualified_constant_defined?` accepts an optional second argument to be
766
766
  able to say whether you want the predicate to look in the ancestors.
767
767
  This flag is taken into account for each constant in the expression while
@@ -792,7 +792,7 @@ N.qualified_const_defined?("C::X") # => true
792
792
  As the last example implies, the second argument defaults to true,
793
793
  as in `const_defined?`.
794
794
 
795
- For coherence with the builtin methods only relative paths are accepted.
795
+ For coherence with the built-in methods only relative paths are accepted.
796
796
  Absolute qualified constant names like `::Math::PI` raise `NameError`.
797
797
 
798
798
  NOTE: Defined in `active_support/core_ext/module/qualified_const.rb`.
@@ -964,20 +964,7 @@ NOTE: Defined in `active_support/core_ext/module/delegation.rb`
964
964
 
965
965
  There are cases where you need to define a method with `define_method`, but don't know whether a method with that name already exists. If it does, a warning is issued if they are enabled. No big deal, but not clean either.
966
966
 
967
- The method `redefine_method` prevents such a potential warning, removing the existing method before if needed. Rails uses it in a few places, for instance when it generates an association's API:
968
-
969
- ```ruby
970
- redefine_method("#{reflection.name}=") do |new_value|
971
- association = association_instance_get(reflection.name)
972
-
973
- if association.nil? || association.target != new_value
974
- association = association_proxy_class.new(self, reflection)
975
- end
976
-
977
- association.replace(new_value)
978
- association_instance_set(reflection.name, new_value.nil? ? nil : association)
979
- end
980
- ```
967
+ The method `redefine_method` prevents such a potential warning, removing the existing method before if needed.
981
968
 
982
969
  NOTE: Defined in `active_support/core_ext/module/remove_method.rb`
983
970
 
@@ -1024,7 +1011,7 @@ self.default_params = {
1024
1011
  }.freeze
1025
1012
  ```
1026
1013
 
1027
- They can be also accessed and overridden at the instance level.
1014
+ They can also be accessed and overridden at the instance level.
1028
1015
 
1029
1016
  ```ruby
1030
1017
  A.x = 1
@@ -1178,9 +1165,9 @@ Inserting data into HTML templates needs extra care. For example, you can't just
1178
1165
 
1179
1166
  #### Safe Strings
1180
1167
 
1181
- Active Support has the concept of <i>(html) safe</i> strings. A safe string is one that is marked as being insertable into HTML as is. It is trusted, no matter whether it has been escaped or not.
1168
+ Active Support has the concept of _(html) safe_ strings. A safe string is one that is marked as being insertable into HTML as is. It is trusted, no matter whether it has been escaped or not.
1182
1169
 
1183
- Strings are considered to be <i>unsafe</i> by default:
1170
+ Strings are considered to be _unsafe_ by default:
1184
1171
 
1185
1172
  ```ruby
1186
1173
  "".html_safe? # => false
@@ -1323,6 +1310,38 @@ In above examples "dear" gets cut first, but then `:separator` prevents it.
1323
1310
 
1324
1311
  NOTE: Defined in `active_support/core_ext/string/filters.rb`.
1325
1312
 
1313
+ ### `truncate_words`
1314
+
1315
+ The method `truncate_words` returns a copy of its receiver truncated after a given number of words:
1316
+
1317
+ ```ruby
1318
+ "Oh dear! Oh dear! I shall be late!".truncate_words(4)
1319
+ # => "Oh dear! Oh dear!..."
1320
+ ```
1321
+
1322
+ Ellipsis can be customized with the `:omission` option:
1323
+
1324
+ ```ruby
1325
+ "Oh dear! Oh dear! I shall be late!".truncate_words(4, omission: '&hellip;')
1326
+ # => "Oh dear! Oh dear!&hellip;"
1327
+ ```
1328
+
1329
+ Pass a `:separator` to truncate the string at a natural break:
1330
+
1331
+ ```ruby
1332
+ "Oh dear! Oh dear! I shall be late!".truncate_words(3, separator: '!')
1333
+ # => "Oh dear! Oh dear! I shall be late..."
1334
+ ```
1335
+
1336
+ The option `:separator` can be a regexp:
1337
+
1338
+ ```ruby
1339
+ "Oh dear! Oh dear! I shall be late!".truncate_words(4, separator: /\s/)
1340
+ # => "Oh dear! Oh dear!..."
1341
+ ```
1342
+
1343
+ NOTE: Defined in `active_support/core_ext/string/filters.rb`.
1344
+
1326
1345
  ### `inquiry`
1327
1346
 
1328
1347
  The `inquiry` method converts a string into a `StringInquirer` object making equality checks prettier.
@@ -1644,6 +1663,9 @@ Given a string with a qualified constant name, `demodulize` returns the very con
1644
1663
  "Product".demodulize # => "Product"
1645
1664
  "Backoffice::UsersController".demodulize # => "UsersController"
1646
1665
  "Admin::Hotel::ReservationUtils".demodulize # => "ReservationUtils"
1666
+ "::Inflections".demodulize # => "Inflections"
1667
+ "".demodulize # => ""
1668
+
1647
1669
  ```
1648
1670
 
1649
1671
  Active Record for example uses this method to compute the name of a counter cache column:
@@ -1778,34 +1800,47 @@ NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1778
1800
 
1779
1801
  #### `humanize`
1780
1802
 
1781
- The method `humanize` gives you a sensible name for display out of an attribute name. To do so it replaces underscores with spaces, removes any "_id" suffix, and capitalizes the first word:
1803
+ The method `humanize` tweaks an attribute name for display to end users.
1804
+
1805
+ Specifically performs these transformations:
1806
+
1807
+ * Applies human inflection rules to the argument.
1808
+ * Deletes leading underscores, if any.
1809
+ * Removes a "_id" suffix if present.
1810
+ * Replaces underscores with spaces, if any.
1811
+ * Downcases all words except acronyms.
1812
+ * Capitalizes the first word.
1813
+
1814
+ The capitalization of the first word can be turned off by setting the
1815
+ +:capitalize+ option to false (default is true).
1782
1816
 
1783
1817
  ```ruby
1784
- "name".humanize # => "Name"
1785
- "author_id".humanize # => "Author"
1786
- "comments_count".humanize # => "Comments count"
1818
+ "name".humanize # => "Name"
1819
+ "author_id".humanize # => "Author"
1820
+ "author_id".humanize(capitalize: false) # => "author"
1821
+ "comments_count".humanize # => "Comments count"
1822
+ "_id".humanize # => "Id"
1787
1823
  ```
1788
1824
 
1789
- The capitalization of the first word can be turned off by setting the optional parameter `capitalize` to false:
1825
+ If "SSL" was defined to be an acronym:
1790
1826
 
1791
1827
  ```ruby
1792
- "author_id".humanize(capitalize: false) # => "author"
1828
+ 'ssl_error'.humanize # => "SSL error"
1793
1829
  ```
1794
1830
 
1795
- The helper method `full_messages` uses `humanize` as a fallback to include attribute names:
1831
+ The helper method `full_messages` uses `humanize` as a fallback to include
1832
+ attribute names:
1796
1833
 
1797
1834
  ```ruby
1798
1835
  def full_messages
1799
- full_messages = []
1800
-
1801
- each do |attribute, messages|
1802
- ...
1803
- attr_name = attribute.to_s.gsub('.', '_').humanize
1804
- attr_name = @base.class.human_attribute_name(attribute, default: attr_name)
1805
- ...
1806
- end
1836
+ map { |attribute, message| full_message(attribute, message) }
1837
+ end
1807
1838
 
1808
- full_messages
1839
+ def full_message
1840
+ ...
1841
+ attr_name = attribute.to_s.tr('.', '_').humanize
1842
+ attr_name = @base.class.human_attribute_name(attribute, default: attr_name)
1843
+ ...
1809
1844
  end
1810
1845
  ```
1811
1846
 
@@ -1915,24 +1950,6 @@ as well as adding or subtracting their results from a Time object. For example:
1915
1950
  (4.months + 5.years).from_now
1916
1951
  ```
1917
1952
 
1918
- While these methods provide precise calculation when used as in the examples above, care
1919
- should be taken to note that this is not true if the result of `months', `years', etc is
1920
- converted before use:
1921
-
1922
- ```ruby
1923
- # equivalent to 30.days.to_i.from_now
1924
- 1.month.to_i.from_now
1925
-
1926
- # equivalent to 365.25.days.to_f.from_now
1927
- 1.year.to_f.from_now
1928
- ```
1929
-
1930
- In such cases, Ruby's core [Date](http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html) and
1931
- [Time](http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html) should be used for precision
1932
- date and time arithmetic.
1933
-
1934
- NOTE: Defined in `active_support/core_ext/numeric/time.rb`.
1935
-
1936
1953
  ### Formatting
1937
1954
 
1938
1955
  Enables the formatting of numbers in a variety of ways.
@@ -2719,11 +2736,14 @@ The method `transform_keys` accepts a block and returns a hash that has applied
2719
2736
  # => {"" => nil, "A" => :a, "1" => 1}
2720
2737
  ```
2721
2738
 
2722
- The result in case of collision is undefined:
2739
+ In case of key collision, one of the values will be chosen. The chosen value may not always be the same given the same hash:
2723
2740
 
2724
2741
  ```ruby
2725
2742
  {"a" => 1, a: 2}.transform_keys { |key| key.to_s.upcase }
2726
- # => {"A" => 2}, in my test, can't rely on this result though
2743
+ # The result could either be
2744
+ # => {"A"=>2}
2745
+ # or
2746
+ # => {"A"=>1}
2727
2747
  ```
2728
2748
 
2729
2749
  This method may be useful for example to build specialized conversions. For instance `stringify_keys` and `symbolize_keys` use `transform_keys` to perform their key conversions:
@@ -2758,11 +2778,14 @@ The method `stringify_keys` returns a hash that has a stringified version of the
2758
2778
  # => {"" => nil, "a" => :a, "1" => 1}
2759
2779
  ```
2760
2780
 
2761
- The result in case of collision is undefined:
2781
+ In case of key collision, one of the values will be chosen. The chosen value may not always be the same given the same hash:
2762
2782
 
2763
2783
  ```ruby
2764
2784
  {"a" => 1, a: 2}.stringify_keys
2765
- # => {"a" => 2}, in my test, can't rely on this result though
2785
+ # The result could either be
2786
+ # => {"a"=>2}
2787
+ # or
2788
+ # => {"a"=>1}
2766
2789
  ```
2767
2790
 
2768
2791
  This method may be useful for example to easily accept both symbols and strings as options. For instance `ActionView::Helpers::FormHelper` defines:
@@ -2799,11 +2822,14 @@ The method `symbolize_keys` returns a hash that has a symbolized version of the
2799
2822
 
2800
2823
  WARNING. Note in the previous example only one key was symbolized.
2801
2824
 
2802
- The result in case of collision is undefined:
2825
+ In case of key collision, one of the values will be chosen. The chosen value may not always be the same given the same hash:
2803
2826
 
2804
2827
  ```ruby
2805
2828
  {"a" => 1, a: 2}.symbolize_keys
2806
- # => {:a=>2}, in my test, can't rely on this result though
2829
+ # The result could either be
2830
+ # => {:a=>2}
2831
+ # or
2832
+ # => {:a=>1}
2807
2833
  ```
2808
2834
 
2809
2835
  This method may be useful for example to easily accept both symbols and strings as options. For instance `ActionController::UrlRewriter` defines
@@ -2848,6 +2874,20 @@ Active Record does not accept unknown options when building associations, for ex
2848
2874
 
2849
2875
  NOTE: Defined in `active_support/core_ext/hash/keys.rb`.
2850
2876
 
2877
+ ### Working with Values
2878
+
2879
+ #### `transform_values` && `transform_values!`
2880
+
2881
+ The method `transform_values` accepts a block and returns a hash that has applied the block operations to each of the values in the receiver.
2882
+
2883
+ ```ruby
2884
+ { nil => nil, 1 => 1, :x => :a }.transform_values { |value| value.to_s.upcase }
2885
+ # => {nil=>"", 1=>"1", :x=>"A"}
2886
+ ```
2887
+ There's also the bang variant `transform_values!` that applies the block operations to values in the very receiver.
2888
+
2889
+ NOTE: Defined in `active_support/core_text/hash/transform_values.rb`.
2890
+
2851
2891
  ### Slicing
2852
2892
 
2853
2893
  Ruby has built-in support for taking slices out of strings and arrays. Active Support extends slicing to hashes:
@@ -2911,7 +2951,7 @@ NOTE: Defined in `active_support/core_ext/hash/indifferent_access.rb`.
2911
2951
 
2912
2952
  ### Compacting
2913
2953
 
2914
- The methods `compact` and `compact!` return a Hash without items with `nil` value.
2954
+ The methods `compact` and `compact!` return a Hash without items with `nil` value.
2915
2955
 
2916
2956
  ```ruby
2917
2957
  {a: 1, b: 2, c: nil}.compact # => {a: 1, b: 2}
@@ -3003,6 +3043,53 @@ The method `Range#overlaps?` says whether any two given ranges have non-void int
3003
3043
 
3004
3044
  NOTE: Defined in `active_support/core_ext/range/overlaps.rb`.
3005
3045
 
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
+
3006
3093
  Extensions to `Date`
3007
3094
  --------------------
3008
3095
 
@@ -3611,9 +3698,9 @@ t.advance(seconds: 1)
3611
3698
 
3612
3699
  #### `Time.current`
3613
3700
 
3614
- Active Support defines `Time.current` to be today in the current time zone. That's like `Time.now`, except that it honors the user time zone, if defined. It also defines `Time.yesterday` and `Time.tomorrow`, and the instance predicates `past?`, `today?`, and `future?`, all of them relative to `Time.current`.
3701
+ Active Support defines `Time.current` to be today in the current time zone. That's like `Time.now`, except that it honors the user time zone, if defined. It also defines the instance predicates `past?`, `today?`, and `future?`, all of them relative to `Time.current`.
3615
3702
 
3616
- When making Time comparisons using methods which honor the user time zone, make sure to use `Time.current` and not `Time.now`. There are cases where the user time zone might be in the future compared to the system time zone, which `Time.today` uses by default. This means `Time.now` may equal `Time.yesterday`.
3703
+ When making Time comparisons using methods which honor the user time zone, make sure to use `Time.current` instead of `Time.now`. There are cases where the user time zone might be in the future compared to the system time zone, which `Time.now` uses by default. This means `Time.now.to_date` may equal `Date.yesterday`.
3617
3704
 
3618
3705
  #### `all_day`, `all_week`, `all_month`, `all_quarter` and `all_year`
3619
3706
 
@@ -3777,7 +3864,7 @@ The name may be given as a symbol or string. A symbol is tested against the bare
3777
3864
 
3778
3865
  TIP: A symbol can represent a fully-qualified constant name as in `:"ActiveRecord::Base"`, so the behavior for symbols is defined for convenience, not because it has to be that way technically.
3779
3866
 
3780
- For example, when an action of `PostsController` is called Rails tries optimistically to use `PostsHelper`. It is OK that the helper module does not exist, so if an exception for that constant name is raised it should be silenced. But it could be the case that `posts_helper.rb` raises a `NameError` due to an actual unknown constant. That should be reraised. The method `missing_name?` provides a way to distinguish both cases:
3867
+ For example, when an action of `ArticlesController` is called Rails tries optimistically to use `ArticlesHelper`. It is OK that the helper module does not exist, so if an exception for that constant name is raised it should be silenced. But it could be the case that `articles_helper.rb` raises a `NameError` due to an actual unknown constant. That should be reraised. The method `missing_name?` provides a way to distinguish both cases:
3781
3868
 
3782
3869
  ```ruby
3783
3870
  def default_helper_module!
@@ -3791,7 +3878,7 @@ rescue NameError => e
3791
3878
  end
3792
3879
  ```
3793
3880
 
3794
- NOTE: Defined in `actionpack/lib/abstract_controller/helpers.rb`.
3881
+ NOTE: Defined in `active_support/core_ext/name_error.rb`.
3795
3882
 
3796
3883
  Extensions to `LoadError`
3797
3884
  -------------------------
@@ -3800,7 +3887,7 @@ Active Support adds `is_missing?` to `LoadError`, and also assigns that class to
3800
3887
 
3801
3888
  Given a path name `is_missing?` tests whether the exception was raised due to that particular file (except perhaps for the ".rb" extension).
3802
3889
 
3803
- For example, when an action of `PostsController` is called Rails tries to load `posts_helper.rb`, but that file may not exist. That's fine, the helper module is not mandatory so Rails silences a load error. But it could be the case that the helper module does exist and in turn requires another library that is missing. In that case Rails must reraise the exception. The method `is_missing?` provides a way to distinguish both cases:
3890
+ For example, when an action of `ArticlesController` is called Rails tries to load `articles_helper.rb`, but that file may not exist. That's fine, the helper module is not mandatory so Rails silences a load error. But it could be the case that the helper module does exist and in turn requires another library that is missing. In that case Rails must reraise the exception. The method `is_missing?` provides a way to distinguish both cases:
3804
3891
 
3805
3892
  ```ruby
3806
3893
  def default_helper_module!
@@ -3814,4 +3901,4 @@ rescue NameError => e
3814
3901
  end
3815
3902
  ```
3816
3903
 
3817
- NOTE: Defined in `actionpack/lib/abstract_controller/helpers.rb`.
3904
+ NOTE: Defined in `active_support/core_ext/load_error.rb`.
@@ -17,7 +17,7 @@ After reading this guide, you will know:
17
17
  Introduction to instrumentation
18
18
  -------------------------------
19
19
 
20
- The instrumentation API provided by Active Support allows developers to provide hooks which other developers may hook into. There are several of these within the Rails framework, as described below in <TODO: link to section detailing each hook point>. With this API, developers can choose to be notified when certain events occur inside their application or another piece of Ruby code.
20
+ The instrumentation API provided by Active Support allows developers to provide hooks which other developers may hook into. There are several of these within the Rails framework, as described below in (TODO: link to section detailing each hook point). With this API, developers can choose to be notified when certain events occur inside their application or another piece of Ruby code.
21
21
 
22
22
  For example, there is a hook provided within Active Record that is called every time Active Record uses an SQL query on a database. This hook could be **subscribed** to, and used to track the number of queries during a certain action. There's another hook around the processing of an action of a controller. This could be used, for instance, to track how long a specific action has taken.
23
23
 
@@ -135,7 +135,9 @@ Action Controller
135
135
  | `:format` | html/js/json/xml etc |
136
136
  | `:method` | HTTP request verb |
137
137
  | `:path` | Request path |
138
+ | `:status` | HTTP status code |
138
139
  | `:view_runtime` | Amount spent in view in ms |
140
+ | `:db_runtime` | Amount spent executing database queries in ms |
139
141
 
140
142
  ```ruby
141
143
  {
@@ -223,11 +225,11 @@ Active Record
223
225
 
224
226
  ### sql.active_record
225
227
 
226
- | Key | Value |
227
- | ------------ | --------------------- |
228
- | `:sql` | SQL statement |
229
- | `:name` | Name of the operation |
230
- | `:object_id` | `self.object_id` |
228
+ | Key | Value |
229
+ | ---------------- | --------------------- |
230
+ | `:sql` | SQL statement |
231
+ | `:name` | Name of the operation |
232
+ | `:connection_id` | `self.object_id` |
231
233
 
232
234
  INFO. The adapters will add their own data as well.
233
235
 
@@ -364,7 +366,7 @@ INFO. Options passed to fetch will be merged with the payload.
364
366
  | ------ | --------------------- |
365
367
  | `:key` | Key used in the store |
366
368
 
367
- INFO. Cache stores my add their own keys
369
+ INFO. Cache stores may add their own keys
368
370
 
369
371
  ```ruby
370
372
  {
@@ -457,6 +459,7 @@ Most times you only care about the data itself. Here is a shortcut to just get t
457
459
  ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args|
458
460
  data = args.extract_options!
459
461
  data # { extra: :information }
462
+ end
460
463
  ```
461
464
 
462
465
  You may also subscribe to events matching a regular expression. This enables you to subscribe to