rails 4.0.0 → 4.2.11.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (190) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +30 -23
  3. data/guides/CHANGELOG.md +108 -6
  4. data/guides/Rakefile +21 -6
  5. data/guides/assets/images/akshaysurve.jpg +0 -0
  6. data/guides/assets/images/edge_badge.png +0 -0
  7. data/guides/assets/images/feature_tile.gif +0 -0
  8. data/guides/assets/images/footer_tile.gif +0 -0
  9. data/guides/assets/images/fxn.png +0 -0
  10. data/guides/assets/images/getting_started/article_with_comments.png +0 -0
  11. data/guides/assets/images/getting_started/challenge.png +0 -0
  12. data/guides/assets/images/getting_started/confirm_dialog.png +0 -0
  13. data/guides/assets/images/getting_started/forbidden_attributes_for_new_article.png +0 -0
  14. data/guides/assets/images/getting_started/form_with_errors.png +0 -0
  15. data/guides/assets/images/getting_started/index_action_with_edit_link.png +0 -0
  16. data/guides/assets/images/getting_started/new_article.png +0 -0
  17. data/guides/assets/images/getting_started/rails_welcome.png +0 -0
  18. data/guides/assets/images/getting_started/routing_error_no_controller.png +0 -0
  19. data/guides/assets/images/getting_started/routing_error_no_route_matches.png +0 -0
  20. data/guides/assets/images/getting_started/show_action_for_articles.png +0 -0
  21. data/guides/assets/images/getting_started/template_is_missing_articles_new.png +0 -0
  22. data/guides/assets/images/getting_started/unknown_action_create_for_articles.png +0 -0
  23. data/guides/assets/images/getting_started/unknown_action_new_for_articles.png +0 -0
  24. data/guides/assets/images/header_tile.gif +0 -0
  25. data/guides/assets/images/icons/README +1 -1
  26. data/guides/assets/images/icons/callouts/11.png +0 -0
  27. data/guides/assets/images/icons/callouts/12.png +0 -0
  28. data/guides/assets/images/icons/callouts/13.png +0 -0
  29. data/guides/assets/images/icons/callouts/15.png +0 -0
  30. data/guides/assets/images/icons/caution.png +0 -0
  31. data/guides/assets/images/icons/example.png +0 -0
  32. data/guides/assets/images/radar.png +0 -0
  33. data/guides/assets/images/rails4_features.png +0 -0
  34. data/guides/assets/images/rails_guides_kindle_cover.jpg +0 -0
  35. data/guides/assets/images/vijaydev.jpg +0 -0
  36. data/guides/assets/javascripts/guides.js +36 -34
  37. data/guides/assets/stylesheets/main.css +6 -2
  38. data/guides/assets/stylesheets/print.css +1 -1
  39. data/guides/bug_report_templates/action_controller_gem.rb +47 -0
  40. data/guides/bug_report_templates/action_controller_master.rb +54 -0
  41. data/guides/bug_report_templates/active_record_gem.rb +5 -2
  42. data/guides/bug_report_templates/active_record_master.rb +3 -2
  43. data/guides/bug_report_templates/generic_gem.rb +15 -0
  44. data/guides/bug_report_templates/generic_master.rb +26 -0
  45. data/guides/rails_guides.rb +23 -4
  46. data/guides/rails_guides/generator.rb +1 -1
  47. data/guides/rails_guides/helpers.rb +4 -2
  48. data/guides/rails_guides/levenshtein.rb +27 -21
  49. data/guides/rails_guides/markdown.rb +11 -7
  50. data/guides/rails_guides/markdown/renderer.rb +1 -1
  51. data/guides/source/2_2_release_notes.md +3 -3
  52. data/guides/source/2_3_release_notes.md +12 -12
  53. data/guides/source/3_0_release_notes.md +10 -13
  54. data/guides/source/3_1_release_notes.md +7 -4
  55. data/guides/source/3_2_release_notes.md +17 -14
  56. data/guides/source/4_0_release_notes.md +110 -54
  57. data/guides/source/4_1_release_notes.md +730 -0
  58. data/guides/source/4_2_release_notes.md +877 -0
  59. data/guides/source/_license.html.erb +1 -1
  60. data/guides/source/_welcome.html.erb +6 -2
  61. data/guides/source/action_controller_overview.md +223 -57
  62. data/guides/source/action_mailer_basics.md +129 -76
  63. data/guides/source/action_view_overview.md +247 -246
  64. data/guides/source/active_job_basics.md +339 -0
  65. data/guides/source/active_model_basics.md +374 -20
  66. data/guides/source/active_record_basics.md +46 -45
  67. data/guides/source/active_record_callbacks.md +83 -28
  68. data/guides/source/{migrations.md → active_record_migrations.md} +191 -275
  69. data/guides/source/active_record_postgresql.md +433 -0
  70. data/guides/source/active_record_querying.md +382 -300
  71. data/guides/source/active_record_validations.md +64 -55
  72. data/guides/source/active_support_core_extensions.md +229 -187
  73. data/guides/source/active_support_instrumentation.md +23 -22
  74. data/guides/source/api_documentation_guidelines.md +167 -15
  75. data/guides/source/asset_pipeline.md +768 -294
  76. data/guides/source/association_basics.md +188 -96
  77. data/guides/source/autoloading_and_reloading_constants.md +1311 -0
  78. data/guides/source/caching_with_rails.md +45 -11
  79. data/guides/source/command_line.md +96 -65
  80. data/guides/source/configuring.md +404 -70
  81. data/guides/source/contributing_to_ruby_on_rails.md +270 -130
  82. data/guides/source/credits.html.erb +7 -3
  83. data/guides/source/debugging_rails_applications.md +471 -284
  84. data/guides/source/development_dependencies_install.md +115 -21
  85. data/guides/source/documents.yaml +31 -9
  86. data/guides/source/engines.md +737 -291
  87. data/guides/source/form_helpers.md +137 -89
  88. data/guides/source/generators.md +60 -28
  89. data/guides/source/getting_started.md +1007 -596
  90. data/guides/source/i18n.md +178 -96
  91. data/guides/source/index.html.erb +2 -1
  92. data/guides/source/initialization.md +248 -104
  93. data/guides/source/kindle/toc.html.erb +1 -1
  94. data/guides/source/layout.html.erb +14 -22
  95. data/guides/source/layouts_and_rendering.md +78 -46
  96. data/guides/source/maintenance_policy.md +78 -0
  97. data/guides/source/nested_model_forms.md +10 -7
  98. data/guides/source/plugins.md +66 -57
  99. data/guides/source/rails_application_templates.md +49 -12
  100. data/guides/source/rails_on_rack.md +50 -60
  101. data/guides/source/routing.md +190 -139
  102. data/guides/source/ruby_on_rails_guides_guidelines.md +12 -13
  103. data/guides/source/security.md +134 -83
  104. data/guides/source/testing.md +322 -200
  105. data/guides/source/upgrading_ruby_on_rails.md +834 -37
  106. data/guides/source/working_with_javascript_in_rails.md +36 -26
  107. data/guides/w3c_validator.rb +2 -0
  108. metadata +93 -116
  109. data/guides/assets/images/getting_started/forbidden_attributes_for_new_post.png +0 -0
  110. data/guides/assets/images/getting_started/new_post.png +0 -0
  111. data/guides/assets/images/getting_started/post_with_comments.png +0 -0
  112. data/guides/assets/images/getting_started/show_action_for_posts.png +0 -0
  113. data/guides/assets/images/getting_started/template_is_missing_posts_new.png +0 -0
  114. data/guides/assets/images/getting_started/undefined_method_post_path.png +0 -0
  115. data/guides/assets/images/getting_started/unknown_action_create_for_posts.png +0 -0
  116. data/guides/assets/images/getting_started/unknown_action_new_for_posts.png +0 -0
  117. data/guides/assets/images/jaimeiniesta.jpg +0 -0
  118. data/guides/code/getting_started/Gemfile +0 -43
  119. data/guides/code/getting_started/Gemfile.lock +0 -150
  120. data/guides/code/getting_started/README.rdoc +0 -28
  121. data/guides/code/getting_started/Rakefile +0 -6
  122. data/guides/code/getting_started/app/assets/javascripts/application.js +0 -16
  123. data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +0 -3
  124. data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +0 -3
  125. data/guides/code/getting_started/app/assets/javascripts/welcome.js.coffee +0 -3
  126. data/guides/code/getting_started/app/assets/stylesheets/application.css +0 -13
  127. data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +0 -3
  128. data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +0 -3
  129. data/guides/code/getting_started/app/assets/stylesheets/welcome.css.scss +0 -3
  130. data/guides/code/getting_started/app/controllers/application_controller.rb +0 -5
  131. data/guides/code/getting_started/app/controllers/comments_controller.rb +0 -17
  132. data/guides/code/getting_started/app/controllers/posts_controller.rb +0 -47
  133. data/guides/code/getting_started/app/controllers/welcome_controller.rb +0 -4
  134. data/guides/code/getting_started/app/helpers/application_helper.rb +0 -2
  135. data/guides/code/getting_started/app/helpers/comments_helper.rb +0 -2
  136. data/guides/code/getting_started/app/helpers/posts_helper.rb +0 -2
  137. data/guides/code/getting_started/app/helpers/welcome_helper.rb +0 -2
  138. data/guides/code/getting_started/app/models/comment.rb +0 -3
  139. data/guides/code/getting_started/app/models/post.rb +0 -7
  140. data/guides/code/getting_started/app/views/comments/_comment.html.erb +0 -15
  141. data/guides/code/getting_started/app/views/comments/_form.html.erb +0 -13
  142. data/guides/code/getting_started/app/views/layouts/application.html.erb +0 -14
  143. data/guides/code/getting_started/app/views/posts/_form.html.erb +0 -27
  144. data/guides/code/getting_started/app/views/posts/edit.html.erb +0 -5
  145. data/guides/code/getting_started/app/views/posts/index.html.erb +0 -21
  146. data/guides/code/getting_started/app/views/posts/new.html.erb +0 -5
  147. data/guides/code/getting_started/app/views/posts/show.html.erb +0 -18
  148. data/guides/code/getting_started/app/views/welcome/index.html.erb +0 -3
  149. data/guides/code/getting_started/bin/bundle +0 -4
  150. data/guides/code/getting_started/bin/rails +0 -4
  151. data/guides/code/getting_started/bin/rake +0 -4
  152. data/guides/code/getting_started/config.ru +0 -4
  153. data/guides/code/getting_started/config/application.rb +0 -18
  154. data/guides/code/getting_started/config/boot.rb +0 -4
  155. data/guides/code/getting_started/config/database.yml +0 -25
  156. data/guides/code/getting_started/config/environment.rb +0 -5
  157. data/guides/code/getting_started/config/environments/development.rb +0 -30
  158. data/guides/code/getting_started/config/environments/production.rb +0 -80
  159. data/guides/code/getting_started/config/environments/test.rb +0 -36
  160. data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +0 -7
  161. data/guides/code/getting_started/config/initializers/filter_parameter_logging.rb +0 -4
  162. data/guides/code/getting_started/config/initializers/inflections.rb +0 -16
  163. data/guides/code/getting_started/config/initializers/locale.rb +0 -9
  164. data/guides/code/getting_started/config/initializers/mime_types.rb +0 -5
  165. data/guides/code/getting_started/config/initializers/secret_token.rb +0 -12
  166. data/guides/code/getting_started/config/initializers/session_store.rb +0 -3
  167. data/guides/code/getting_started/config/initializers/wrap_parameters.rb +0 -14
  168. data/guides/code/getting_started/config/locales/en.yml +0 -23
  169. data/guides/code/getting_started/config/routes.rb +0 -7
  170. data/guides/code/getting_started/db/migrate/20130122042648_create_posts.rb +0 -10
  171. data/guides/code/getting_started/db/migrate/20130122045842_create_comments.rb +0 -11
  172. data/guides/code/getting_started/db/schema.rb +0 -33
  173. data/guides/code/getting_started/db/seeds.rb +0 -7
  174. data/guides/code/getting_started/public/404.html +0 -58
  175. data/guides/code/getting_started/public/422.html +0 -58
  176. data/guides/code/getting_started/public/500.html +0 -57
  177. data/guides/code/getting_started/public/favicon.ico +0 -0
  178. data/guides/code/getting_started/public/robots.txt +0 -5
  179. data/guides/code/getting_started/test/controllers/comments_controller_test.rb +0 -7
  180. data/guides/code/getting_started/test/controllers/posts_controller_test.rb +0 -7
  181. data/guides/code/getting_started/test/controllers/welcome_controller_test.rb +0 -9
  182. data/guides/code/getting_started/test/fixtures/comments.yml +0 -11
  183. data/guides/code/getting_started/test/fixtures/posts.yml +0 -9
  184. data/guides/code/getting_started/test/helpers/comments_helper_test.rb +0 -4
  185. data/guides/code/getting_started/test/helpers/posts_helper_test.rb +0 -4
  186. data/guides/code/getting_started/test/helpers/welcome_helper_test.rb +0 -4
  187. data/guides/code/getting_started/test/models/comment_test.rb +0 -7
  188. data/guides/code/getting_started/test/models/post_test.rb +0 -7
  189. data/guides/code/getting_started/test/test_helper.rb +0 -15
  190. data/guides/source/kindle/KINDLE.md +0 -26
@@ -85,7 +85,7 @@ end
85
85
  We can see how it works by looking at some `rails console` output:
86
86
 
87
87
  ```ruby
88
- $ rails console
88
+ $ bin/rails console
89
89
  >> p = Person.new(name: "John Doe")
90
90
  => #<Person id: nil, name: "John Doe", created_at: nil, updated_at: nil>
91
91
  >> p.new_record?
@@ -120,8 +120,8 @@ database only if the object is valid:
120
120
  * `update!`
121
121
 
122
122
  The bang versions (e.g. `save!`) raise an exception if the record is invalid.
123
- The non-bang versions don't: `save` and `update` return `false`,
124
- `create` and `update` just return the objects.
123
+ The non-bang versions don't, `save` and `update` return `false`,
124
+ `create` just returns the object.
125
125
 
126
126
  ### Skipping Validations
127
127
 
@@ -162,8 +162,8 @@ Person.create(name: nil).valid? # => false
162
162
  ```
163
163
 
164
164
  After Active Record has performed validations, any errors found can be accessed
165
- through the `errors` instance method, which returns a collection of errors. By
166
- definition, an object is valid if this collection is empty after running
165
+ through the `errors.messages` instance method, which returns a collection of errors.
166
+ By definition, an object is valid if this collection is empty after running
167
167
  validations.
168
168
 
169
169
  Note that an object instantiated with `new` will not report errors even if it's
@@ -175,28 +175,28 @@ class Person < ActiveRecord::Base
175
175
  end
176
176
 
177
177
  >> p = Person.new
178
- #=> #<Person id: nil, name: nil>
179
- >> p.errors
180
- #=> {}
178
+ # => #<Person id: nil, name: nil>
179
+ >> p.errors.messages
180
+ # => {}
181
181
 
182
182
  >> p.valid?
183
- #=> false
184
- >> p.errors
185
- #=> {name:["can't be blank"]}
183
+ # => false
184
+ >> p.errors.messages
185
+ # => {name:["can't be blank"]}
186
186
 
187
187
  >> p = Person.create
188
- #=> #<Person id: nil, name: nil>
189
- >> p.errors
190
- #=> {name:["can't be blank"]}
188
+ # => #<Person id: nil, name: nil>
189
+ >> p.errors.messages
190
+ # => {name:["can't be blank"]}
191
191
 
192
192
  >> p.save
193
- #=> false
193
+ # => false
194
194
 
195
195
  >> p.save!
196
- #=> ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
196
+ # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
197
197
 
198
198
  >> Person.create!
199
- #=> ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
199
+ # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
200
200
  ```
201
201
 
202
202
  `invalid?` is simply the inverse of `valid?`. It triggers your validations,
@@ -243,7 +243,7 @@ line of code you can add the same kind of validation to several attributes.
243
243
  All of them accept the `:on` and `:message` options, which define when the
244
244
  validation should be run and what message should be added to the `errors`
245
245
  collection if it fails, respectively. The `:on` option takes one of the values
246
- `:save` (the default), `:create` or `:update`. There is a default error
246
+ `:create` or `:update`. There is a default error
247
247
  message for each one of the validation helpers. These messages are used when
248
248
  the `:message` option isn't specified. Let's take a look at each one of the
249
249
  available helpers.
@@ -337,7 +337,7 @@ set. In fact, this set can be any enumerable object.
337
337
  ```ruby
338
338
  class Account < ActiveRecord::Base
339
339
  validates :subdomain, exclusion: { in: %w(www us ca jp),
340
- message: "Subdomain %{value} is reserved." }
340
+ message: "%{value} is reserved." }
341
341
  end
342
342
  ```
343
343
 
@@ -357,10 +357,12 @@ given regular expression, which is specified using the `:with` option.
357
357
  ```ruby
358
358
  class Product < ActiveRecord::Base
359
359
  validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/,
360
- message: "Only letters allowed" }
360
+ message: "only allows letters" }
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
  }
@@ -438,8 +440,6 @@ provide a personalized message or use `presence: true` instead. When
438
440
  `:in` or `:within` have a lower limit of 1, you should either provide a
439
441
  personalized message or call `presence` prior to `length`.
440
442
 
441
- The `size` helper is an alias for `length`.
442
-
443
443
  ### `numericality`
444
444
 
445
445
  This helper validates that your attributes have only numeric values. By
@@ -526,9 +526,16 @@ If you validate the presence of an object associated via a `has_one` or
526
526
  `marked_for_destruction?`.
527
527
 
528
528
  Since `false.blank?` is true, if you want to validate the presence of a boolean
529
- 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
+ ```
530
536
 
531
- The default error message is _"can't be empty"_.
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.
532
539
 
533
540
  ### `absence`
534
541
 
@@ -577,7 +584,9 @@ This helper validates that the attribute's value is unique right before the
577
584
  object gets saved. It does not create a uniqueness constraint in the database,
578
585
  so it may happen that two different database connections create two records
579
586
  with the same value for a column that you intend to be unique. To avoid that,
580
- you must create a unique index in your database.
587
+ you must create a unique index on both columns in your database. See
588
+ [the MySQL manual](http://dev.mysql.com/doc/refman/5.6/en/multiple-column-indexes.html)
589
+ for more details about multiple column indexes.
581
590
 
582
591
  ```ruby
583
592
  class Account < ActiveRecord::Base
@@ -618,10 +627,6 @@ The default error message is _"has already been taken"_.
618
627
  This helper passes the record to a separate class for validation.
619
628
 
620
629
  ```ruby
621
- class Person < ActiveRecord::Base
622
- validates_with GoodnessValidator
623
- end
624
-
625
630
  class GoodnessValidator < ActiveModel::Validator
626
631
  def validate(record)
627
632
  if record.first_name == "Evil"
@@ -629,6 +634,10 @@ class GoodnessValidator < ActiveModel::Validator
629
634
  end
630
635
  end
631
636
  end
637
+
638
+ class Person < ActiveRecord::Base
639
+ validates_with GoodnessValidator
640
+ end
632
641
  ```
633
642
 
634
643
  NOTE: Errors added to `record.errors[:base]` relate to the state of the record
@@ -646,10 +655,6 @@ Like all other validations, `validates_with` takes the `:if`, `:unless` and
646
655
  validator class as `options`:
647
656
 
648
657
  ```ruby
649
- class Person < ActiveRecord::Base
650
- validates_with GoodnessValidator, fields: [:first_name, :last_name]
651
- end
652
-
653
658
  class GoodnessValidator < ActiveModel::Validator
654
659
  def validate(record)
655
660
  if options[:fields].any?{|field| record.send(field) == "Evil" }
@@ -657,6 +662,10 @@ class GoodnessValidator < ActiveModel::Validator
657
662
  end
658
663
  end
659
664
  end
665
+
666
+ class Person < ActiveRecord::Base
667
+ validates_with GoodnessValidator, fields: [:first_name, :last_name]
668
+ end
660
669
  ```
661
670
 
662
671
  Note that the validator will be initialized *only once* for the whole application
@@ -677,14 +686,14 @@ class GoodnessValidator
677
686
  def initialize(person)
678
687
  @person = person
679
688
  end
680
-
689
+
681
690
  def validate
682
691
  if some_complex_condition_involving_ivars_and_private_methods?
683
692
  @person.errors[:base] << "This person is evil"
684
693
  end
685
694
  end
686
-
687
- #
695
+
696
+ # ...
688
697
  end
689
698
  ```
690
699
 
@@ -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
  ```
@@ -736,8 +745,8 @@ class Topic < ActiveRecord::Base
736
745
  validates :title, length: { is: 5 }, allow_blank: true
737
746
  end
738
747
 
739
- Topic.create("title" => "").valid? # => true
740
- Topic.create("title" => nil).valid? # => true
748
+ Topic.create(title: "").valid? # => true
749
+ Topic.create(title: nil).valid? # => true
741
750
  ```
742
751
 
743
752
  ### `:message`
@@ -765,10 +774,9 @@ class Person < ActiveRecord::Base
765
774
  validates :age, numericality: true, on: :update
766
775
 
767
776
  # the default (validates on both create and update)
768
- validates :name, presence: true, on: :save
777
+ validates :name, presence: true
769
778
  end
770
779
  ```
771
- The last line is in review state and as of now, it is not running in any version of Rails 3.2.x as discussed in this [issue](https://github.com/rails/rails/issues/10248)
772
780
 
773
781
  Strict Validations
774
782
  ------------------
@@ -784,7 +792,7 @@ end
784
792
  Person.new.valid? # => ActiveModel::StrictValidationFailed: Name can't be blank
785
793
  ```
786
794
 
787
- There is also an ability to pass custom exception to `:strict` option
795
+ There is also an ability to pass custom exception to `:strict` option.
788
796
 
789
797
  ```ruby
790
798
  class Person < ActiveRecord::Base
@@ -872,7 +880,7 @@ should happen, an `Array` can be used. Moreover, you can apply both `:if` and
872
880
  ```ruby
873
881
  class Computer < ActiveRecord::Base
874
882
  validates :mouse, presence: true,
875
- if: ["market.retail?", :desktop?]
883
+ if: ["market.retail?", :desktop?],
876
884
  unless: Proc.new { |c| c.trackpad.present? }
877
885
  end
878
886
  ```
@@ -911,8 +919,8 @@ end
911
919
  The easiest way to add custom validators for validating individual attributes
912
920
  is with the convenient `ActiveModel::EachValidator`. In this case, the custom
913
921
  validator class must implement a `validate_each` method which takes three
914
- arguments: record, attribute and value which correspond to the instance, the
915
- 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
916
924
  instance.
917
925
 
918
926
  ```ruby
@@ -936,8 +944,9 @@ own custom validators.
936
944
 
937
945
  You can also create methods that verify the state of your models and add
938
946
  messages to the `errors` collection when they are invalid. You must then
939
- register these methods by using the `validate` class method, passing in the
940
- symbols for the validation methods' names.
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.
941
950
 
942
951
  You can pass more than one symbol for each class method and the respective
943
952
  validations will be run in the same order as they were registered.
@@ -993,12 +1002,12 @@ end
993
1002
 
994
1003
  person = Person.new
995
1004
  person.valid? # => false
996
- person.errors
1005
+ person.errors.messages
997
1006
  # => {:name=>["can't be blank", "is too short (minimum is 3 characters)"]}
998
1007
 
999
1008
  person = Person.new(name: "John Doe")
1000
1009
  person.valid? # => true
1001
- person.errors # => []
1010
+ person.errors.messages # => {}
1002
1011
  ```
1003
1012
 
1004
1013
  ### `errors[]`
@@ -1130,15 +1139,15 @@ generating a scaffold, Rails will put some ERB into the `_form.html.erb` that
1130
1139
  it generates that displays the full list of errors on that model.
1131
1140
 
1132
1141
  Assuming we have a model that's been saved in an instance variable named
1133
- `@post`, it looks like this:
1142
+ `@article`, it looks like this:
1134
1143
 
1135
1144
  ```ruby
1136
- <% if @post.errors.any? %>
1145
+ <% if @article.errors.any? %>
1137
1146
  <div id="error_explanation">
1138
- <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>
1147
+ <h2><%= pluralize(@article.errors.count, "error") %> prohibited this article from being saved:</h2>
1139
1148
 
1140
1149
  <ul>
1141
- <% @post.errors.full_messages.each do |msg| %>
1150
+ <% @article.errors.full_messages.each do |msg| %>
1142
1151
  <li><%= msg %></li>
1143
1152
  <% end %>
1144
1153
  </ul>
@@ -1152,7 +1161,7 @@ the entry.
1152
1161
 
1153
1162
  ```
1154
1163
  <div class="field_with_errors">
1155
- <input id="post_title" name="post[title]" size="30" type="text" value="">
1164
+ <input id="article_title" name="article[title]" size="30" type="text" value="">
1156
1165
  </div>
1157
1166
  ```
1158
1167
 
@@ -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 this single call is enough:
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 `ActionDispatch::Session::AbstractStore` uses `blank?` for checking whether a session key is present:
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 ensure_session_key!
103
- if @key.blank?
104
- raise ArgumentError, 'A key is required...'
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
  ```
@@ -153,12 +157,12 @@ Active Support provides `duplicable?` to programmatically query an object about
153
157
 
154
158
  ```ruby
155
159
  "foo".duplicable? # => true
156
- "".duplicable? # => true
160
+ "".duplicable? # => true
157
161
  0.0.duplicable? # => false
158
- false.duplicable? # => false
162
+ false.duplicable? # => false
159
163
  ```
160
164
 
161
- 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.
162
166
 
163
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.
164
168
 
@@ -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, 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:
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 #=> ['string']
179
- duplicate #=> ['string', 'another-string']
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 #=> ['foo']
185
- duplicate #=> ['foo', 'another-string']
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 #=> ['string']
199
- duplicate #=> ['foo']
202
+ array # => ['string']
203
+ duplicate # => ['foo']
200
204
  ```
201
205
 
202
206
  If the object is not duplicable, `deep_dup` will just return it:
@@ -418,6 +422,12 @@ TIP: Since `with_options` forwards calls to its receiver they can be nested. Eac
418
422
 
419
423
  NOTE: Defined in `active_support/core_ext/object/with_options.rb`.
420
424
 
425
+ ### JSON support
426
+
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.
428
+
429
+ NOTE: Defined in `active_support/core_ext/object/json.rb`.
430
+
421
431
  ### Instance Variables
422
432
 
423
433
  Active Support provides several methods to ease access to instance variables.
@@ -439,6 +449,22 @@ C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
439
449
 
440
450
  NOTE: Defined in `active_support/core_ext/object/instance_variables.rb`.
441
451
 
452
+ #### `instance_variable_names`
453
+
454
+ The method `instance_variable_names` returns an array. Each name includes the "@" sign.
455
+
456
+ ```ruby
457
+ class C
458
+ def initialize(x, y)
459
+ @x, @y = x, y
460
+ end
461
+ end
462
+
463
+ C.new(0, 1).instance_variable_names # => ["@x", "@y"]
464
+ ```
465
+
466
+ NOTE: Defined in `active_support/core_ext/object/instance_variables.rb`.
467
+
442
468
  ### Silencing Warnings, Streams, and Exceptions
443
469
 
444
470
  The methods `silence_warnings` and `enable_warnings` change the value of `$VERBOSE` accordingly for the duration of their block, and reset it afterwards:
@@ -546,12 +572,12 @@ NOTE: Defined in `active_support/core_ext/module/aliasing.rb`.
546
572
 
547
573
  #### `alias_attribute`
548
574
 
549
- 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):
550
576
 
551
577
  ```ruby
552
578
  class User < ActiveRecord::Base
553
- # let me refer to the email column as "login",
554
- # possibly meaningful for authentication code
579
+ # You can refer to the email column as "login".
580
+ # This can be meaningful for authentication code.
555
581
  alias_attribute :login, :email
556
582
  end
557
583
  ```
@@ -598,7 +624,7 @@ NOTE: Defined in `active_support/core_ext/module/attr_internal.rb`.
598
624
 
599
625
  #### Module Attributes
600
626
 
601
- The macros `mattr_reader`, `mattr_writer`, and `mattr_accessor` are analogous to the `cattr_*` macros defined for class. Check [Class Attributes](#class-attributes).
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).
602
628
 
603
629
  For example, the dependencies mechanism uses them:
604
630
 
@@ -709,7 +735,7 @@ X.local_constants # => [:X1, :X2, :Y]
709
735
  X::Y.local_constants # => [:Y1, :X1]
710
736
  ```
711
737
 
712
- The names are returned as symbols. (The deprecated method `local_constant_names` returns strings.)
738
+ The names are returned as symbols.
713
739
 
714
740
  NOTE: Defined in `active_support/core_ext/module/introspection.rb`.
715
741
 
@@ -735,7 +761,7 @@ Arguments may be bare constant names:
735
761
  Math.qualified_const_get("E") # => 2.718281828459045
736
762
  ```
737
763
 
738
- These methods are analogous to their builtin counterparts. In particular,
764
+ These methods are analogous to their built-in counterparts. In particular,
739
765
  `qualified_constant_defined?` accepts an optional second argument to be
740
766
  able to say whether you want the predicate to look in the ancestors.
741
767
  This flag is taken into account for each constant in the expression while
@@ -766,7 +792,7 @@ N.qualified_const_defined?("C::X") # => true
766
792
  As the last example implies, the second argument defaults to true,
767
793
  as in `const_defined?`.
768
794
 
769
- For coherence with the builtin methods only relative paths are accepted.
795
+ For coherence with the built-in methods only relative paths are accepted.
770
796
  Absolute qualified constant names like `::Math::PI` raise `NameError`.
771
797
 
772
798
  NOTE: Defined in `active_support/core_ext/module/qualified_const.rb`.
@@ -862,7 +888,7 @@ class User < ActiveRecord::Base
862
888
  end
863
889
  ```
864
890
 
865
- With that configuration you get a user's name via his profile, `user.profile.name`, but it could be handy to still be able to access such attribute directly:
891
+ With that configuration you get a user's name via their profile, `user.profile.name`, but it could be handy to still be able to access such attribute directly:
866
892
 
867
893
  ```ruby
868
894
  class User < ActiveRecord::Base
@@ -938,20 +964,7 @@ NOTE: Defined in `active_support/core_ext/module/delegation.rb`
938
964
 
939
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.
940
966
 
941
- 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:
942
-
943
- ```ruby
944
- redefine_method("#{reflection.name}=") do |new_value|
945
- association = association_instance_get(reflection.name)
946
-
947
- if association.nil? || association.target != new_value
948
- association = association_proxy_class.new(self, reflection)
949
- end
950
-
951
- association.replace(new_value)
952
- association_instance_set(reflection.name, new_value.nil? ? nil : association)
953
- end
954
- ```
967
+ The method `redefine_method` prevents such a potential warning, removing the existing method before if needed.
955
968
 
956
969
  NOTE: Defined in `active_support/core_ext/module/remove_method.rb`
957
970
 
@@ -998,7 +1011,7 @@ self.default_params = {
998
1011
  }.freeze
999
1012
  ```
1000
1013
 
1001
- They can be also accessed and overridden at the instance level.
1014
+ They can also be accessed and overridden at the instance level.
1002
1015
 
1003
1016
  ```ruby
1004
1017
  A.x = 1
@@ -1038,7 +1051,7 @@ For convenience `class_attribute` also defines an instance predicate which is th
1038
1051
 
1039
1052
  When `:instance_reader` is `false`, the instance predicate returns a `NoMethodError` just like the reader method.
1040
1053
 
1041
- If you do not want the instance predicate, pass `instance_predicate: false` and it will not be defined.
1054
+ If you do not want the instance predicate, pass `instance_predicate: false` and it will not be defined.
1042
1055
 
1043
1056
  NOTE: Defined in `active_support/core_ext/class/attribute.rb`
1044
1057
 
@@ -1067,6 +1080,15 @@ end
1067
1080
 
1068
1081
  we can access `field_error_proc` in views.
1069
1082
 
1083
+ Also, you can pass a block to `cattr_*` to set up the attribute with a default value:
1084
+
1085
+ ```ruby
1086
+ class MysqlAdapter < AbstractAdapter
1087
+ # Generates class methods to access @@emulate_booleans with default value of true.
1088
+ cattr_accessor(:emulate_booleans) { true }
1089
+ end
1090
+ ```
1091
+
1070
1092
  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.
1071
1093
 
1072
1094
  ```ruby
@@ -1084,7 +1106,7 @@ end
1084
1106
 
1085
1107
  A model may find it useful to set `:instance_accessor` to `false` as a way to prevent mass-assignment from setting the attribute.
1086
1108
 
1087
- NOTE: Defined in `active_support/core_ext/class/attribute_accessors.rb`.
1109
+ NOTE: Defined in `active_support/core_ext/module/attribute_accessors.rb`.
1088
1110
 
1089
1111
  ### Subclasses & Descendants
1090
1112
 
@@ -1143,9 +1165,9 @@ Inserting data into HTML templates needs extra care. For example, you can't just
1143
1165
 
1144
1166
  #### Safe Strings
1145
1167
 
1146
- 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.
1147
1169
 
1148
- Strings are considered to be <i>unsafe</i> by default:
1170
+ Strings are considered to be _unsafe_ by default:
1149
1171
 
1150
1172
  ```ruby
1151
1173
  "".html_safe? # => false
@@ -1224,6 +1246,18 @@ Calling `to_s` on a safe string returns a safe string, but coercion with `to_str
1224
1246
 
1225
1247
  Calling `dup` or `clone` on safe strings yields safe strings.
1226
1248
 
1249
+ ### `remove`
1250
+
1251
+ The method `remove` will remove all occurrences of the pattern:
1252
+
1253
+ ```ruby
1254
+ "Hello World".remove(/Hello /) => "World"
1255
+ ```
1256
+
1257
+ There's also the destructive version `String#remove!`.
1258
+
1259
+ NOTE: Defined in `active_support/core_ext/string/filters.rb`.
1260
+
1227
1261
  ### `squish`
1228
1262
 
1229
1263
  The method `squish` strips leading and trailing whitespace, and substitutes runs of whitespace with a single space each:
@@ -1234,7 +1268,7 @@ The method `squish` strips leading and trailing whitespace, and substitutes runs
1234
1268
 
1235
1269
  There's also the destructive version `String#squish!`.
1236
1270
 
1237
- Note that it handles both ASCII and Unicode whitespace like mongolian vowel separator (U+180E).
1271
+ Note that it handles both ASCII and Unicode whitespace.
1238
1272
 
1239
1273
  NOTE: Defined in `active_support/core_ext/string/filters.rb`.
1240
1274
 
@@ -1276,6 +1310,38 @@ In above examples "dear" gets cut first, but then `:separator` prevents it.
1276
1310
 
1277
1311
  NOTE: Defined in `active_support/core_ext/string/filters.rb`.
1278
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
+
1279
1345
  ### `inquiry`
1280
1346
 
1281
1347
  The `inquiry` method converts a string into a `StringInquirer` object making equality checks prettier.
@@ -1356,6 +1422,8 @@ The third argument, `indent_empty_lines`, is a flag that says whether empty line
1356
1422
 
1357
1423
  The `indent!` method performs indentation in-place.
1358
1424
 
1425
+ NOTE: Defined in `active_support/core_ext/string/indent.rb`.
1426
+
1359
1427
  ### Access
1360
1428
 
1361
1429
  #### `at(position)`
@@ -1423,7 +1491,7 @@ The method `pluralize` returns the plural of its receiver:
1423
1491
 
1424
1492
  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.
1425
1493
 
1426
- `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:
1494
+ `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:
1427
1495
 
1428
1496
  ```ruby
1429
1497
  "dude".pluralize(0) # => "dudes"
@@ -1507,7 +1575,7 @@ ActiveSupport::Inflector.inflections do |inflect|
1507
1575
  inflect.acronym 'SSL'
1508
1576
  end
1509
1577
 
1510
- "SSLError".underscore.camelize #=> "SSLError"
1578
+ "SSLError".underscore.camelize # => "SSLError"
1511
1579
  ```
1512
1580
 
1513
1581
  `camelize` is aliased to `camelcase`.
@@ -1595,6 +1663,9 @@ Given a string with a qualified constant name, `demodulize` returns the very con
1595
1663
  "Product".demodulize # => "Product"
1596
1664
  "Backoffice::UsersController".demodulize # => "UsersController"
1597
1665
  "Admin::Hotel::ReservationUtils".demodulize # => "ReservationUtils"
1666
+ "::Inflections".demodulize # => "Inflections"
1667
+ "".demodulize # => ""
1668
+
1598
1669
  ```
1599
1670
 
1600
1671
  Active Record for example uses this method to compute the name of a counter cache column:
@@ -1689,7 +1760,7 @@ NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1689
1760
  The method `constantize` resolves the constant reference expression in its receiver:
1690
1761
 
1691
1762
  ```ruby
1692
- "Fixnum".constantize # => Fixnum
1763
+ "Integer".constantize # => Integer
1693
1764
 
1694
1765
  module M
1695
1766
  X = 1
@@ -1729,28 +1800,47 @@ NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
1729
1800
 
1730
1801
  #### `humanize`
1731
1802
 
1732
- 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).
1733
1816
 
1734
1817
  ```ruby
1735
- "name".humanize # => "Name"
1736
- "author_id".humanize # => "Author"
1737
- "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"
1738
1823
  ```
1739
1824
 
1740
- The helper method `full_messages` uses `humanize` as a fallback to include attribute names:
1825
+ If "SSL" was defined to be an acronym:
1741
1826
 
1742
1827
  ```ruby
1743
- def full_messages
1744
- full_messages = []
1828
+ 'ssl_error'.humanize # => "SSL error"
1829
+ ```
1745
1830
 
1746
- each do |attribute, messages|
1747
- ...
1748
- attr_name = attribute.to_s.gsub('.', '_').humanize
1749
- attr_name = @base.class.human_attribute_name(attribute, default: attr_name)
1750
- ...
1751
- end
1831
+ The helper method `full_messages` uses `humanize` as a fallback to include
1832
+ attribute names:
1752
1833
 
1753
- full_messages
1834
+ ```ruby
1835
+ def full_messages
1836
+ map { |attribute, message| full_message(attribute, message) }
1837
+ end
1838
+
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
+ ...
1754
1844
  end
1755
1845
  ```
1756
1846
 
@@ -1860,24 +1950,6 @@ as well as adding or subtracting their results from a Time object. For example:
1860
1950
  (4.months + 5.years).from_now
1861
1951
  ```
1862
1952
 
1863
- While these methods provide precise calculation when used as in the examples above, care
1864
- should be taken to note that this is not true if the result of `months', `years', etc is
1865
- converted before use:
1866
-
1867
- ```ruby
1868
- # equivalent to 30.days.to_i.from_now
1869
- 1.month.to_i.from_now
1870
-
1871
- # equivalent to 365.25.days.to_f.from_now
1872
- 1.year.to_f.from_now
1873
- ```
1874
-
1875
- In such cases, Ruby's core [Date](http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html) and
1876
- [Time](http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html) should be used for precision
1877
- date and time arithmetic.
1878
-
1879
- NOTE: Defined in `active_support/core_ext/numeric/time.rb`.
1880
-
1881
1953
  ### Formatting
1882
1954
 
1883
1955
  Enables the formatting of numbers in a variety of ways.
@@ -1963,7 +2035,7 @@ Produce a string representation of a number in human-readable words:
1963
2035
  1234567890123456.to_s(:human) # => "1.23 Quadrillion"
1964
2036
  ```
1965
2037
 
1966
- NOTE: Defined in `active_support/core_ext/numeric/formatting.rb`.
2038
+ NOTE: Defined in `active_support/core_ext/numeric/conversions.rb`.
1967
2039
 
1968
2040
  Extensions to `Integer`
1969
2041
  -----------------------
@@ -2011,8 +2083,33 @@ NOTE: Defined in `active_support/core_ext/integer/inflections.rb`.
2011
2083
 
2012
2084
  Extensions to `BigDecimal`
2013
2085
  --------------------------
2086
+ ### `to_s`
2014
2087
 
2015
- ...
2088
+ The method `to_s` is aliased to `to_formatted_s`. This provides a convenient way to display a BigDecimal value in floating-point notation:
2089
+
2090
+ ```ruby
2091
+ BigDecimal.new(5.00, 6).to_s # => "5.0"
2092
+ ```
2093
+
2094
+ ### `to_formatted_s`
2095
+
2096
+ Te method `to_formatted_s` provides a default specifier of "F". This means that a simple call to `to_formatted_s` or `to_s` will result in floating point representation instead of engineering notation:
2097
+
2098
+ ```ruby
2099
+ BigDecimal.new(5.00, 6).to_formatted_s # => "5.0"
2100
+ ```
2101
+
2102
+ and that symbol specifiers are also supported:
2103
+
2104
+ ```ruby
2105
+ BigDecimal.new(5.00, 6).to_formatted_s(:db) # => "5.0"
2106
+ ```
2107
+
2108
+ Engineering notation is still supported:
2109
+
2110
+ ```ruby
2111
+ BigDecimal.new(5.00, 6).to_formatted_s("e") # => "0.5E1"
2112
+ ```
2016
2113
 
2017
2114
  Extensions to `Enumerable`
2018
2115
  --------------------------
@@ -2207,8 +2304,6 @@ The defaults for these options can be localized, their keys are:
2207
2304
  | `:words_connector` | `support.array.words_connector` |
2208
2305
  | `:last_word_connector` | `support.array.last_word_connector` |
2209
2306
 
2210
- Options `:connector` and `:skip_last_comma` are deprecated.
2211
-
2212
2307
  NOTE: Defined in `active_support/core_ext/array/conversions.rb`.
2213
2308
 
2214
2309
  #### `to_formatted_s`
@@ -2383,7 +2478,7 @@ dup[1][2] = 4
2383
2478
  array[1][2] == nil # => true
2384
2479
  ```
2385
2480
 
2386
- NOTE: Defined in `active_support/core_ext/array/deep_dup.rb`.
2481
+ NOTE: Defined in `active_support/core_ext/object/deep_dup.rb`.
2387
2482
 
2388
2483
  ### Grouping
2389
2484
 
@@ -2517,8 +2612,7 @@ To do so, the method loops over the pairs and builds nodes that depend on the _v
2517
2612
  ```ruby
2518
2613
  XML_TYPE_NAMES = {
2519
2614
  "Symbol" => "symbol",
2520
- "Fixnum" => "integer",
2521
- "Bignum" => "integer",
2615
+ "Integer" => "integer",
2522
2616
  "BigDecimal" => "decimal",
2523
2617
  "Float" => "float",
2524
2618
  "TrueClass" => "boolean",
@@ -2609,45 +2703,7 @@ hash[:b][:e] == nil # => true
2609
2703
  hash[:b][:d] == [3, 4] # => true
2610
2704
  ```
2611
2705
 
2612
- NOTE: Defined in `active_support/core_ext/hash/deep_dup.rb`.
2613
-
2614
- ### Diffing
2615
-
2616
- The method `diff` returns a hash that represents a diff of the receiver and the argument with the following logic:
2617
-
2618
- * Pairs `key`, `value` that exist in both hashes do not belong to the diff hash.
2619
-
2620
- * If both hashes have `key`, but with different values, the pair in the receiver wins.
2621
-
2622
- * The rest is just merged.
2623
-
2624
- ```ruby
2625
- {a: 1}.diff(a: 1)
2626
- # => {}, first rule
2627
-
2628
- {a: 1}.diff(a: 2)
2629
- # => {:a=>1}, second rule
2630
-
2631
- {a: 1}.diff(b: 2)
2632
- # => {:a=>1, :b=>2}, third rule
2633
-
2634
- {a: 1, b: 2, c: 3}.diff(b: 1, c: 3, d: 4)
2635
- # => {:a=>1, :b=>2, :d=>4}, all rules
2636
-
2637
- {}.diff({}) # => {}
2638
- {a: 1}.diff({}) # => {:a=>1}
2639
- {}.diff(a: 1) # => {:a=>1}
2640
- ```
2641
-
2642
- An important property of this diff hash is that you can retrieve the original hash by applying `diff` twice:
2643
-
2644
- ```ruby
2645
- hash.diff(hash2).diff(hash2) == hash
2646
- ```
2647
-
2648
- Diffing hashes may be useful for error messages related to expected option hashes for example.
2649
-
2650
- NOTE: Defined in `active_support/core_ext/hash/diff.rb`.
2706
+ NOTE: Defined in `active_support/core_ext/object/deep_dup.rb`.
2651
2707
 
2652
2708
  ### Working with Keys
2653
2709
 
@@ -2675,26 +2731,29 @@ NOTE: Defined in `active_support/core_ext/hash/except.rb`.
2675
2731
  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:
2676
2732
 
2677
2733
  ```ruby
2678
- {nil => nil, 1 => 1, a: :a}.transform_keys{ |key| key.to_s.upcase }
2734
+ {nil => nil, 1 => 1, a: :a}.transform_keys { |key| key.to_s.upcase }
2679
2735
  # => {"" => nil, "A" => :a, "1" => 1}
2680
2736
  ```
2681
2737
 
2682
- The result in case of collision is undefined:
2738
+ 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:
2683
2739
 
2684
2740
  ```ruby
2685
- {"a" => 1, a: 2}.transform_keys{ |key| key.to_s.upcase }
2686
- # => {"A" => 2}, in my test, can't rely on this result though
2741
+ {"a" => 1, a: 2}.transform_keys { |key| key.to_s.upcase }
2742
+ # The result could either be
2743
+ # => {"A"=>2}
2744
+ # or
2745
+ # => {"A"=>1}
2687
2746
  ```
2688
2747
 
2689
2748
  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:
2690
2749
 
2691
2750
  ```ruby
2692
2751
  def stringify_keys
2693
- transform_keys{ |key| key.to_s }
2752
+ transform_keys { |key| key.to_s }
2694
2753
  end
2695
2754
  ...
2696
2755
  def symbolize_keys
2697
- transform_keys{ |key| key.to_sym rescue key }
2756
+ transform_keys { |key| key.to_sym rescue key }
2698
2757
  end
2699
2758
  ```
2700
2759
 
@@ -2703,7 +2762,7 @@ There's also the bang variant `transform_keys!` that applies the block operation
2703
2762
  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:
2704
2763
 
2705
2764
  ```ruby
2706
- {nil => nil, 1 => 1, nested: {a: 3, 5 => 5}}.deep_transform_keys{ |key| key.to_s.upcase }
2765
+ {nil => nil, 1 => 1, nested: {a: 3, 5 => 5}}.deep_transform_keys { |key| key.to_s.upcase }
2707
2766
  # => {""=>nil, "1"=>1, "NESTED"=>{"A"=>3, "5"=>5}}
2708
2767
  ```
2709
2768
 
@@ -2718,11 +2777,14 @@ The method `stringify_keys` returns a hash that has a stringified version of the
2718
2777
  # => {"" => nil, "a" => :a, "1" => 1}
2719
2778
  ```
2720
2779
 
2721
- The result in case of collision is undefined:
2780
+ 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:
2722
2781
 
2723
2782
  ```ruby
2724
2783
  {"a" => 1, a: 2}.stringify_keys
2725
- # => {"a" => 2}, in my test, can't rely on this result though
2784
+ # The result could either be
2785
+ # => {"a"=>2}
2786
+ # or
2787
+ # => {"a"=>1}
2726
2788
  ```
2727
2789
 
2728
2790
  This method may be useful for example to easily accept both symbols and strings as options. For instance `ActionView::Helpers::FormHelper` defines:
@@ -2759,11 +2821,14 @@ The method `symbolize_keys` returns a hash that has a symbolized version of the
2759
2821
 
2760
2822
  WARNING. Note in the previous example only one key was symbolized.
2761
2823
 
2762
- The result in case of collision is undefined:
2824
+ 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:
2763
2825
 
2764
2826
  ```ruby
2765
2827
  {"a" => 1, a: 2}.symbolize_keys
2766
- # => {:a=>2}, in my test, can't rely on this result though
2828
+ # The result could either be
2829
+ # => {:a=>2}
2830
+ # or
2831
+ # => {:a=>1}
2767
2832
  ```
2768
2833
 
2769
2834
  This method may be useful for example to easily accept both symbols and strings as options. For instance `ActionController::UrlRewriter` defines
@@ -2808,6 +2873,20 @@ Active Record does not accept unknown options when building associations, for ex
2808
2873
 
2809
2874
  NOTE: Defined in `active_support/core_ext/hash/keys.rb`.
2810
2875
 
2876
+ ### Working with Values
2877
+
2878
+ #### `transform_values` && `transform_values!`
2879
+
2880
+ 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.
2881
+
2882
+ ```ruby
2883
+ { nil => nil, 1 => 1, :x => :a }.transform_values { |value| value.to_s.upcase }
2884
+ # => {nil=>"", 1=>"1", :x=>"A"}
2885
+ ```
2886
+ There's also the bang variant `transform_values!` that applies the block operations to values in the very receiver.
2887
+
2888
+ NOTE: Defined in `active_support/core_text/hash/transform_values.rb`.
2889
+
2811
2890
  ### Slicing
2812
2891
 
2813
2892
  Ruby has built-in support for taking slices out of strings and arrays. Active Support extends slicing to hashes:
@@ -2869,6 +2948,16 @@ The method `with_indifferent_access` returns an `ActiveSupport::HashWithIndiffer
2869
2948
 
2870
2949
  NOTE: Defined in `active_support/core_ext/hash/indifferent_access.rb`.
2871
2950
 
2951
+ ### Compacting
2952
+
2953
+ The methods `compact` and `compact!` return a Hash without items with `nil` value.
2954
+
2955
+ ```ruby
2956
+ {a: 1, b: 2, c: nil}.compact # => {a: 1, b: 2}
2957
+ ```
2958
+
2959
+ NOTE: Defined in `active_support/core_ext/hash/compact.rb`.
2960
+
2872
2961
  Extensions to `Regexp`
2873
2962
  ----------------------
2874
2963
 
@@ -2953,53 +3042,6 @@ The method `Range#overlaps?` says whether any two given ranges have non-void int
2953
3042
 
2954
3043
  NOTE: Defined in `active_support/core_ext/range/overlaps.rb`.
2955
3044
 
2956
- Extensions to `Proc`
2957
- --------------------
2958
-
2959
- ### `bind`
2960
-
2961
- 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:
2962
-
2963
- ```ruby
2964
- Hash.instance_method(:delete) # => #<UnboundMethod: Hash#delete>
2965
- ```
2966
-
2967
- An unbound method is not callable as is, you need to bind it first to an object with `bind`:
2968
-
2969
- ```ruby
2970
- clear = Hash.instance_method(:clear)
2971
- clear.bind({a: 1}).call # => {}
2972
- ```
2973
-
2974
- Active Support defines `Proc#bind` with an analogous purpose:
2975
-
2976
- ```ruby
2977
- Proc.new { size }.bind([]).call # => 0
2978
- ```
2979
-
2980
- As you see that's callable and bound to the argument, the return value is indeed a `Method`.
2981
-
2982
- 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.
2983
-
2984
- 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:
2985
-
2986
- ```ruby
2987
- def handler_for_rescue(exception)
2988
- _, rescuer = Array(rescue_handlers).reverse.detect do |klass_name, handler|
2989
- ...
2990
- end
2991
-
2992
- case rescuer
2993
- when Symbol
2994
- method(rescuer)
2995
- when Proc
2996
- rescuer.bind(self)
2997
- end
2998
- end
2999
- ```
3000
-
3001
- NOTE: Defined in `active_support/core_ext/proc.rb`.
3002
-
3003
3045
  Extensions to `Date`
3004
3046
  --------------------
3005
3047
 
@@ -3608,9 +3650,9 @@ t.advance(seconds: 1)
3608
3650
 
3609
3651
  #### `Time.current`
3610
3652
 
3611
- 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`.
3653
+ 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`.
3612
3654
 
3613
- 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`.
3655
+ 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`.
3614
3656
 
3615
3657
  #### `all_day`, `all_week`, `all_month`, `all_quarter` and `all_year`
3616
3658
 
@@ -3774,7 +3816,7 @@ The name may be given as a symbol or string. A symbol is tested against the bare
3774
3816
 
3775
3817
  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.
3776
3818
 
3777
- 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:
3819
+ 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:
3778
3820
 
3779
3821
  ```ruby
3780
3822
  def default_helper_module!
@@ -3782,7 +3824,7 @@ def default_helper_module!
3782
3824
  module_path = module_name.underscore
3783
3825
  helper module_path
3784
3826
  rescue MissingSourceFile => e
3785
- raise e unless e.is_missing? "#{module_path}_helper"
3827
+ raise e unless e.is_missing? "helpers/#{module_path}_helper"
3786
3828
  rescue NameError => e
3787
3829
  raise e unless e.missing_name? "#{module_name}Helper"
3788
3830
  end
@@ -3797,7 +3839,7 @@ Active Support adds `is_missing?` to `LoadError`, and also assigns that class to
3797
3839
 
3798
3840
  Given a path name `is_missing?` tests whether the exception was raised due to that particular file (except perhaps for the ".rb" extension).
3799
3841
 
3800
- 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:
3842
+ 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:
3801
3843
 
3802
3844
  ```ruby
3803
3845
  def default_helper_module!