rails 4.1.4 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -10
- data/guides/CHANGELOG.md +15 -25
- data/guides/Rakefile +5 -3
- data/guides/assets/javascripts/guides.js +6 -0
- data/guides/assets/stylesheets/main.css +4 -1
- data/guides/bug_report_templates/action_controller_gem.rb +2 -2
- data/guides/bug_report_templates/action_controller_master.rb +3 -2
- data/guides/rails_guides/helpers.rb +1 -1
- data/guides/rails_guides/levenshtein.rb +29 -21
- data/guides/rails_guides/markdown/renderer.rb +1 -1
- data/guides/rails_guides/markdown.rb +11 -7
- data/guides/rails_guides.rb +2 -2
- data/guides/source/2_2_release_notes.md +1 -1
- data/guides/source/2_3_release_notes.md +4 -4
- data/guides/source/3_0_release_notes.md +8 -8
- data/guides/source/3_1_release_notes.md +5 -2
- data/guides/source/3_2_release_notes.md +6 -3
- data/guides/source/4_0_release_notes.md +6 -3
- data/guides/source/4_1_release_notes.md +10 -11
- data/guides/source/4_2_release_notes.md +850 -0
- data/guides/source/_license.html.erb +1 -1
- data/guides/source/_welcome.html.erb +2 -8
- data/guides/source/action_controller_overview.md +84 -10
- data/guides/source/action_mailer_basics.md +91 -28
- data/guides/source/action_view_overview.md +140 -130
- data/guides/source/active_job_basics.md +318 -0
- data/guides/source/active_model_basics.md +371 -17
- data/guides/source/active_record_basics.md +19 -18
- data/guides/source/active_record_callbacks.md +12 -9
- data/guides/source/{migrations.md → active_record_migrations.md} +135 -226
- data/guides/source/active_record_postgresql.md +433 -0
- data/guides/source/active_record_querying.md +269 -259
- data/guides/source/active_record_validations.md +21 -12
- data/guides/source/active_support_core_extensions.md +113 -73
- data/guides/source/active_support_instrumentation.md +10 -7
- data/guides/source/api_documentation_guidelines.md +62 -16
- data/guides/source/asset_pipeline.md +264 -67
- data/guides/source/association_basics.md +81 -74
- data/guides/source/caching_with_rails.md +32 -7
- data/guides/source/command_line.md +52 -30
- data/guides/source/configuring.md +132 -29
- data/guides/source/constant_autoloading_and_reloading.md +1297 -0
- data/guides/source/contributing_to_ruby_on_rails.md +192 -112
- data/guides/source/credits.html.erb +2 -2
- data/guides/source/debugging_rails_applications.md +448 -294
- data/guides/source/development_dependencies_install.md +47 -36
- data/guides/source/documents.yaml +19 -7
- data/guides/source/engines.md +210 -189
- data/guides/source/form_helpers.md +79 -56
- data/guides/source/generators.md +24 -11
- data/guides/source/getting_started.md +339 -201
- data/guides/source/i18n.md +111 -68
- data/guides/source/index.html.erb +1 -0
- data/guides/source/initialization.md +109 -62
- data/guides/source/layout.html.erb +1 -4
- data/guides/source/layouts_and_rendering.md +18 -17
- data/guides/source/maintenance_policy.md +26 -4
- data/guides/source/nested_model_forms.md +7 -4
- data/guides/source/plugins.md +27 -27
- data/guides/source/rails_application_templates.md +21 -3
- data/guides/source/rails_on_rack.md +12 -9
- data/guides/source/routing.md +100 -74
- data/guides/source/ruby_on_rails_guides_guidelines.md +11 -12
- data/guides/source/security.md +40 -34
- data/guides/source/testing.md +188 -117
- data/guides/source/upgrading_ruby_on_rails.md +284 -29
- data/guides/source/working_with_javascript_in_rails.md +18 -16
- data/guides/w3c_validator.rb +2 -0
- metadata +40 -94
- data/guides/code/getting_started/Gemfile +0 -40
- data/guides/code/getting_started/Gemfile.lock +0 -125
- data/guides/code/getting_started/README.rdoc +0 -28
- data/guides/code/getting_started/Rakefile +0 -6
- data/guides/code/getting_started/app/assets/javascripts/application.js +0 -15
- data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/javascripts/welcome.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/application.css +0 -13
- data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/welcome.css.scss +0 -3
- data/guides/code/getting_started/app/controllers/application_controller.rb +0 -5
- data/guides/code/getting_started/app/controllers/comments_controller.rb +0 -23
- data/guides/code/getting_started/app/controllers/posts_controller.rb +0 -53
- data/guides/code/getting_started/app/controllers/welcome_controller.rb +0 -4
- data/guides/code/getting_started/app/helpers/application_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/comments_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/posts_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/welcome_helper.rb +0 -2
- data/guides/code/getting_started/app/models/comment.rb +0 -3
- data/guides/code/getting_started/app/models/post.rb +0 -7
- data/guides/code/getting_started/app/views/comments/_comment.html.erb +0 -15
- data/guides/code/getting_started/app/views/comments/_form.html.erb +0 -13
- data/guides/code/getting_started/app/views/layouts/application.html.erb +0 -14
- data/guides/code/getting_started/app/views/posts/_form.html.erb +0 -27
- data/guides/code/getting_started/app/views/posts/edit.html.erb +0 -5
- data/guides/code/getting_started/app/views/posts/index.html.erb +0 -21
- data/guides/code/getting_started/app/views/posts/new.html.erb +0 -5
- data/guides/code/getting_started/app/views/posts/show.html.erb +0 -18
- data/guides/code/getting_started/app/views/welcome/index.html.erb +0 -4
- data/guides/code/getting_started/bin/bundle +0 -4
- data/guides/code/getting_started/bin/rails +0 -4
- data/guides/code/getting_started/bin/rake +0 -4
- data/guides/code/getting_started/config/application.rb +0 -18
- data/guides/code/getting_started/config/boot.rb +0 -4
- data/guides/code/getting_started/config/database.yml +0 -25
- data/guides/code/getting_started/config/environment.rb +0 -5
- data/guides/code/getting_started/config/environments/development.rb +0 -30
- data/guides/code/getting_started/config/environments/production.rb +0 -80
- data/guides/code/getting_started/config/environments/test.rb +0 -36
- data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +0 -7
- data/guides/code/getting_started/config/initializers/filter_parameter_logging.rb +0 -4
- data/guides/code/getting_started/config/initializers/inflections.rb +0 -16
- data/guides/code/getting_started/config/initializers/locale.rb +0 -9
- data/guides/code/getting_started/config/initializers/mime_types.rb +0 -5
- data/guides/code/getting_started/config/initializers/secret_token.rb +0 -12
- data/guides/code/getting_started/config/initializers/session_store.rb +0 -3
- data/guides/code/getting_started/config/initializers/wrap_parameters.rb +0 -14
- data/guides/code/getting_started/config/locales/en.yml +0 -23
- data/guides/code/getting_started/config/routes.rb +0 -7
- data/guides/code/getting_started/config.ru +0 -4
- data/guides/code/getting_started/db/migrate/20130122042648_create_posts.rb +0 -10
- data/guides/code/getting_started/db/migrate/20130122045842_create_comments.rb +0 -11
- data/guides/code/getting_started/db/schema.rb +0 -33
- data/guides/code/getting_started/db/seeds.rb +0 -7
- data/guides/code/getting_started/public/404.html +0 -60
- data/guides/code/getting_started/public/422.html +0 -60
- data/guides/code/getting_started/public/500.html +0 -59
- data/guides/code/getting_started/public/favicon.ico +0 -0
- data/guides/code/getting_started/public/robots.txt +0 -5
- data/guides/code/getting_started/test/controllers/comments_controller_test.rb +0 -7
- data/guides/code/getting_started/test/controllers/posts_controller_test.rb +0 -7
- data/guides/code/getting_started/test/controllers/welcome_controller_test.rb +0 -9
- data/guides/code/getting_started/test/fixtures/comments.yml +0 -11
- data/guides/code/getting_started/test/fixtures/posts.yml +0 -9
- data/guides/code/getting_started/test/helpers/comments_helper_test.rb +0 -4
- data/guides/code/getting_started/test/helpers/posts_helper_test.rb +0 -4
- data/guides/code/getting_started/test/helpers/welcome_helper_test.rb +0 -4
- data/guides/code/getting_started/test/models/comment_test.rb +0 -7
- data/guides/code/getting_started/test/models/post_test.rb +0 -7
- data/guides/code/getting_started/test/test_helper.rb +0 -12
@@ -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.
|
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
|
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
|
-
|
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[
|
710
|
+
record.errors.add(attr, 'must start with upper case') if value =~ /\A[[:lower:]]/
|
702
711
|
end
|
703
712
|
end
|
704
713
|
```
|
@@ -871,7 +880,7 @@ should happen, an `Array` can be used. Moreover, you can apply both `:if` and
|
|
871
880
|
```ruby
|
872
881
|
class Computer < ActiveRecord::Base
|
873
882
|
validates :mouse, presence: true,
|
874
|
-
if: ["market.retail?", :desktop?]
|
883
|
+
if: ["market.retail?", :desktop?],
|
875
884
|
unless: Proc.new { |c| c.trackpad.present? }
|
876
885
|
end
|
877
886
|
```
|
@@ -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
|
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
|
-
`@
|
1141
|
+
`@article`, it looks like this:
|
1133
1142
|
|
1134
1143
|
```ruby
|
1135
|
-
<% if @
|
1144
|
+
<% if @article.errors.any? %>
|
1136
1145
|
<div id="error_explanation">
|
1137
|
-
<h2><%= pluralize(@
|
1146
|
+
<h2><%= pluralize(@article.errors.count, "error") %> prohibited this article from being saved:</h2>
|
1138
1147
|
|
1139
1148
|
<ul>
|
1140
|
-
<% @
|
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="
|
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?
|
160
|
+
"".duplicable? # => true
|
161
161
|
0.0.duplicable? # => false
|
162
|
-
false.duplicable?
|
162
|
+
false.duplicable? # => false
|
163
163
|
```
|
164
164
|
|
165
|
-
By definition all objects are `duplicable?` except `nil`, `false`, `true`, symbols, numbers, class, and
|
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 (
|
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
|
-
#
|
580
|
-
#
|
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
|
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
|
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.
|
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
|
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
|
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
|
1170
|
+
Strings are considered to be _unsafe_ by default:
|
1184
1171
|
|
1185
1172
|
```ruby
|
1186
1173
|
"".html_safe? # => false
|
@@ -1281,7 +1268,7 @@ The method `squish` strips leading and trailing whitespace, and substitutes runs
|
|
1281
1268
|
|
1282
1269
|
There's also the destructive version `String#squish!`.
|
1283
1270
|
|
1284
|
-
Note that it handles both ASCII and Unicode whitespace
|
1271
|
+
Note that it handles both ASCII and Unicode whitespace.
|
1285
1272
|
|
1286
1273
|
NOTE: Defined in `active_support/core_ext/string/filters.rb`.
|
1287
1274
|
|
@@ -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: '…')
|
1326
|
+
# => "Oh dear! Oh dear!…"
|
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`
|
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
|
1785
|
-
"author_id".humanize
|
1786
|
-
"
|
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
|
-
|
1825
|
+
If "SSL" was defined to be an acronym:
|
1790
1826
|
|
1791
1827
|
```ruby
|
1792
|
-
|
1828
|
+
'ssl_error'.humanize # => "SSL error"
|
1793
1829
|
```
|
1794
1830
|
|
1795
|
-
The helper method `full_messages` uses `humanize` as a fallback to include
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
#
|
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
|
-
|
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
|
-
#
|
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
|
-
|
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
|
-
#
|
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}
|
@@ -3658,9 +3698,9 @@ t.advance(seconds: 1)
|
|
3658
3698
|
|
3659
3699
|
#### `Time.current`
|
3660
3700
|
|
3661
|
-
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
|
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`.
|
3662
3702
|
|
3663
|
-
When making Time comparisons using methods which honor the user time zone, make sure to use `Time.current`
|
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`.
|
3664
3704
|
|
3665
3705
|
#### `all_day`, `all_week`, `all_month`, `all_quarter` and `all_year`
|
3666
3706
|
|
@@ -3824,7 +3864,7 @@ The name may be given as a symbol or string. A symbol is tested against the bare
|
|
3824
3864
|
|
3825
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.
|
3826
3866
|
|
3827
|
-
For example, when an action of `
|
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:
|
3828
3868
|
|
3829
3869
|
```ruby
|
3830
3870
|
def default_helper_module!
|
@@ -3838,7 +3878,7 @@ rescue NameError => e
|
|
3838
3878
|
end
|
3839
3879
|
```
|
3840
3880
|
|
3841
|
-
NOTE: Defined in `
|
3881
|
+
NOTE: Defined in `active_support/core_ext/name_error.rb`.
|
3842
3882
|
|
3843
3883
|
Extensions to `LoadError`
|
3844
3884
|
-------------------------
|
@@ -3847,7 +3887,7 @@ Active Support adds `is_missing?` to `LoadError`, and also assigns that class to
|
|
3847
3887
|
|
3848
3888
|
Given a path name `is_missing?` tests whether the exception was raised due to that particular file (except perhaps for the ".rb" extension).
|
3849
3889
|
|
3850
|
-
For example, when an action of `
|
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:
|
3851
3891
|
|
3852
3892
|
```ruby
|
3853
3893
|
def default_helper_module!
|
@@ -3861,4 +3901,4 @@ rescue NameError => e
|
|
3861
3901
|
end
|
3862
3902
|
```
|
3863
3903
|
|
3864
|
-
NOTE: Defined in `
|
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
|
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
|
227
|
-
|
|
228
|
-
| `:sql`
|
229
|
-
| `:name`
|
230
|
-
| `:
|
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
|
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
|
@@ -13,7 +13,19 @@ After reading this guide, you will know:
|
|
13
13
|
RDoc
|
14
14
|
----
|
15
15
|
|
16
|
-
The Rails API documentation
|
16
|
+
The [Rails API documentation](http://api.rubyonrails.org) is generated with
|
17
|
+
[RDoc](http://docs.seattlerb.org/rdoc/).
|
18
|
+
|
19
|
+
```bash
|
20
|
+
bundle exec rake rdoc
|
21
|
+
```
|
22
|
+
|
23
|
+
Resulting HTML files can be found in the ./doc/rdoc directory.
|
24
|
+
|
25
|
+
Please consult the RDoc documentation for help with the
|
26
|
+
[markup](http://docs.seattlerb.org/rdoc/RDoc/Markup.html),
|
27
|
+
and also take into account these [additional
|
28
|
+
directives](http://docs.seattlerb.org/rdoc/RDoc/Parser/Ruby.html).
|
17
29
|
|
18
30
|
Wording
|
19
31
|
-------
|
@@ -67,7 +79,7 @@ used. Instead of:
|
|
67
79
|
English
|
68
80
|
-------
|
69
81
|
|
70
|
-
Please use American English (
|
82
|
+
Please use American English (*color*, *center*, *modularize*, etc). See [a list of American and British English spelling differences here](http://en.wikipedia.org/wiki/American_and_British_English_spelling_differences).
|
71
83
|
|
72
84
|
Example Code
|
73
85
|
------------
|
@@ -110,14 +122,14 @@ The results of expressions follow them and are introduced by "# => ", vertically
|
|
110
122
|
If a line is too long, the comment may be placed on the next line:
|
111
123
|
|
112
124
|
```ruby
|
113
|
-
# label(:
|
114
|
-
# # => <label for="
|
125
|
+
# label(:article, :title)
|
126
|
+
# # => <label for="article_title">Title</label>
|
115
127
|
#
|
116
|
-
# label(:
|
117
|
-
# # => <label for="
|
128
|
+
# label(:article, :title, "A short title")
|
129
|
+
# # => <label for="article_title">A short title</label>
|
118
130
|
#
|
119
|
-
# label(:
|
120
|
-
# # => <label for="
|
131
|
+
# label(:article, :title, "A short title", class: "title_label")
|
132
|
+
# # => <label for="article_title" class="title_label">A short title</label>
|
121
133
|
```
|
122
134
|
|
123
135
|
Avoid using any printing methods like `puts` or `p` for that purpose.
|
@@ -175,8 +187,8 @@ end
|
|
175
187
|
The API is careful not to commit to any particular value, the method has
|
176
188
|
predicate semantics, that's enough.
|
177
189
|
|
178
|
-
|
179
|
-
|
190
|
+
File Names
|
191
|
+
----------
|
180
192
|
|
181
193
|
As a rule of thumb, use filenames relative to the application root:
|
182
194
|
|
@@ -215,6 +227,13 @@ ordinary method names, symbols, paths (with forward slashes), etc. Please use
|
|
215
227
|
`<tt>...</tt>` for everything else, notably class or module names with a
|
216
228
|
namespace as in `<tt>ActiveRecord::Base</tt>`.
|
217
229
|
|
230
|
+
You can quickly test the RDoc output with the following command:
|
231
|
+
|
232
|
+
```
|
233
|
+
$ echo "+:to_param+" | rdoc --pipe
|
234
|
+
#=> <p><code>:to_param</code></p>
|
235
|
+
```
|
236
|
+
|
218
237
|
### Regular Font
|
219
238
|
|
220
239
|
When "true" and "false" are English words rather than Ruby keywords use a regular font:
|
@@ -283,7 +302,7 @@ self.class_eval %{
|
|
283
302
|
Method Visibility
|
284
303
|
-----------------
|
285
304
|
|
286
|
-
When writing documentation for Rails, it's important to understand the difference between public
|
305
|
+
When writing documentation for Rails, it's important to understand the difference between public user-facing API vs internal API.
|
287
306
|
|
288
307
|
Rails, like most libraries, uses the private keyword from Ruby for defining internal API. However, public API follows a slightly different convention. Instead of assuming all public methods are designed for user consumption, Rails uses the `:nodoc:` directive to annotate these kinds of methods as internal API.
|
289
308
|
|
@@ -299,17 +318,44 @@ module ActiveRecord::Core::ClassMethods
|
|
299
318
|
end
|
300
319
|
```
|
301
320
|
|
302
|
-
If you thought, "this method looks like a public class method for `ActiveRecord::Core`", you were right. But actually the Rails team doesn't want users to rely on this method. So they mark it as `:nodoc:` and it's removed from public documentation. The reasoning behind this is to allow the team to change these methods according to their internal needs across releases as they see fit. The name of this method could change, or the return value, or this entire class may disappear; there's no guarantee and so you shouldn't depend on this API in your
|
321
|
+
If you thought, "this method looks like a public class method for `ActiveRecord::Core`", you were right. But actually the Rails team doesn't want users to rely on this method. So they mark it as `:nodoc:` and it's removed from public documentation. The reasoning behind this is to allow the team to change these methods according to their internal needs across releases as they see fit. The name of this method could change, or the return value, or this entire class may disappear; there's no guarantee and so you shouldn't depend on this API in your plugins or applications. Otherwise, you risk your app or gem breaking when you upgrade to a newer release of Rails.
|
303
322
|
|
304
|
-
As a contributor, it's important to think about whether this API is meant for end-user consumption. The Rails team is committed to not making any breaking changes to public API across releases without going through a full deprecation cycle
|
323
|
+
As a contributor, it's important to think about whether this API is meant for end-user consumption. The Rails team is committed to not making any breaking changes to public API across releases without going through a full deprecation cycle. It's recommended that you `:nodoc:` any of your internal methods/classes unless they're already private (meaning visibility), in which case it's internal by default. Once the API stabilizes the visibility can change, but changing public API is much harder due to backwards compatibility.
|
305
324
|
|
306
325
|
A class or module is marked with `:nodoc:` to indicate that all methods are internal API and should never be used directly.
|
307
326
|
|
308
|
-
If you come across an existing `:nodoc:` you should tread lightly. Consider asking someone from the core team or author of the code before removing it. This should almost always happen through a
|
327
|
+
If you come across an existing `:nodoc:` you should tread lightly. Consider asking someone from the core team or author of the code before removing it. This should almost always happen through a pull request instead of the docrails project.
|
309
328
|
|
310
329
|
A `:nodoc:` should never be added simply because a method or class is missing documentation. There may be an instance where an internal public method wasn't given a `:nodoc:` by mistake, for example when switching a method from private to public visibility. When this happens it should be discussed over a PR on a case-by-case basis and never committed directly to docrails.
|
311
330
|
|
312
|
-
To summarize, the Rails team uses `:nodoc:` to mark publicly visible methods and classes for internal use; changes to the visibility of API should be considered carefully and discussed over a
|
331
|
+
To summarize, the Rails team uses `:nodoc:` to mark publicly visible methods and classes for internal use; changes to the visibility of API should be considered carefully and discussed over a pull request first.
|
332
|
+
|
333
|
+
Regarding the Rails Stack
|
334
|
+
-------------------------
|
335
|
+
|
336
|
+
When documenting parts of Rails API, it's important to remember all of the
|
337
|
+
pieces that go into the Rails stack.
|
338
|
+
|
339
|
+
This means that behavior may change depending on the scope or context of the
|
340
|
+
method or class you're trying to document.
|
341
|
+
|
342
|
+
In various places there is different behavior when you take the entire stack
|
343
|
+
into account, one such example is
|
344
|
+
`ActionView::Helpers::AssetTagHelper#image_tag`:
|
345
|
+
|
346
|
+
```ruby
|
347
|
+
# image_tag("icon.png")
|
348
|
+
# # => <img alt="Icon" src="/assets/icon.png" />
|
349
|
+
```
|
350
|
+
|
351
|
+
Although the default behavior for `#image_tag` is to always return
|
352
|
+
`/images/icon.png`, we take into account the full Rails stack (including the
|
353
|
+
Asset Pipeline) we may see the result seen above.
|
354
|
+
|
355
|
+
We're only concerned with the behavior experienced when using the full default
|
356
|
+
Rails stack.
|
313
357
|
|
314
|
-
|
358
|
+
In this case, we want to document the behavior of the _framework_, and not just
|
359
|
+
this specific method.
|
315
360
|
|
361
|
+
If you have a question on how the Rails team handles certain API, don't hesitate to open a ticket or send a patch to the [issue tracker](https://github.com/rails/rails/issues).
|