rails 4.1.16 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -10
  3. data/guides/CHANGELOG.md +15 -100
  4. data/guides/Rakefile +5 -3
  5. data/guides/assets/javascripts/guides.js +6 -0
  6. data/guides/assets/stylesheets/main.css +4 -1
  7. data/guides/bug_report_templates/action_controller_master.rb +1 -0
  8. data/guides/rails_guides/helpers.rb +1 -1
  9. data/guides/rails_guides/levenshtein.rb +29 -21
  10. data/guides/rails_guides/markdown/renderer.rb +1 -1
  11. data/guides/rails_guides/markdown.rb +11 -7
  12. data/guides/rails_guides.rb +2 -2
  13. data/guides/source/2_2_release_notes.md +1 -1
  14. data/guides/source/2_3_release_notes.md +4 -4
  15. data/guides/source/3_0_release_notes.md +8 -8
  16. data/guides/source/3_1_release_notes.md +6 -3
  17. data/guides/source/3_2_release_notes.md +6 -3
  18. data/guides/source/4_0_release_notes.md +6 -3
  19. data/guides/source/4_1_release_notes.md +5 -6
  20. data/guides/source/4_2_release_notes.md +850 -0
  21. data/guides/source/_license.html.erb +1 -1
  22. data/guides/source/_welcome.html.erb +2 -8
  23. data/guides/source/action_controller_overview.md +81 -7
  24. data/guides/source/action_mailer_basics.md +91 -28
  25. data/guides/source/action_view_overview.md +148 -130
  26. data/guides/source/active_job_basics.md +318 -0
  27. data/guides/source/active_model_basics.md +371 -17
  28. data/guides/source/active_record_basics.md +19 -18
  29. data/guides/source/active_record_callbacks.md +12 -9
  30. data/guides/source/{migrations.md → active_record_migrations.md} +95 -220
  31. data/guides/source/active_record_postgresql.md +433 -0
  32. data/guides/source/active_record_querying.md +263 -265
  33. data/guides/source/active_record_validations.md +20 -11
  34. data/guides/source/active_support_core_extensions.md +159 -72
  35. data/guides/source/active_support_instrumentation.md +10 -7
  36. data/guides/source/api_documentation_guidelines.md +62 -16
  37. data/guides/source/asset_pipeline.md +258 -63
  38. data/guides/source/association_basics.md +81 -74
  39. data/guides/source/caching_with_rails.md +32 -7
  40. data/guides/source/command_line.md +52 -30
  41. data/guides/source/configuring.md +132 -29
  42. data/guides/source/constant_autoloading_and_reloading.md +1297 -0
  43. data/guides/source/contributing_to_ruby_on_rails.md +192 -112
  44. data/guides/source/credits.html.erb +2 -2
  45. data/guides/source/debugging_rails_applications.md +440 -286
  46. data/guides/source/development_dependencies_install.md +47 -36
  47. data/guides/source/documents.yaml +19 -7
  48. data/guides/source/engines.md +182 -182
  49. data/guides/source/form_helpers.md +79 -56
  50. data/guides/source/generators.md +24 -11
  51. data/guides/source/getting_started.md +337 -198
  52. data/guides/source/i18n.md +108 -65
  53. data/guides/source/index.html.erb +1 -0
  54. data/guides/source/initialization.md +108 -61
  55. data/guides/source/layout.html.erb +1 -4
  56. data/guides/source/layouts_and_rendering.md +27 -25
  57. data/guides/source/maintenance_policy.md +6 -3
  58. data/guides/source/nested_model_forms.md +7 -4
  59. data/guides/source/plugins.md +27 -27
  60. data/guides/source/rails_application_templates.md +21 -3
  61. data/guides/source/rails_on_rack.md +8 -4
  62. data/guides/source/routing.md +98 -72
  63. data/guides/source/ruby_on_rails_guides_guidelines.md +11 -12
  64. data/guides/source/security.md +38 -32
  65. data/guides/source/testing.md +188 -117
  66. data/guides/source/upgrading_ruby_on_rails.md +254 -28
  67. data/guides/source/working_with_javascript_in_rails.md +18 -16
  68. data/guides/w3c_validator.rb +2 -0
  69. metadata +40 -96
  70. data/guides/bug_report_templates/generic_gem.rb +0 -15
  71. data/guides/bug_report_templates/generic_master.rb +0 -26
  72. data/guides/code/getting_started/Gemfile +0 -40
  73. data/guides/code/getting_started/Gemfile.lock +0 -125
  74. data/guides/code/getting_started/README.rdoc +0 -28
  75. data/guides/code/getting_started/Rakefile +0 -6
  76. data/guides/code/getting_started/app/assets/javascripts/application.js +0 -15
  77. data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +0 -3
  78. data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +0 -3
  79. data/guides/code/getting_started/app/assets/javascripts/welcome.js.coffee +0 -3
  80. data/guides/code/getting_started/app/assets/stylesheets/application.css +0 -13
  81. data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +0 -3
  82. data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +0 -3
  83. data/guides/code/getting_started/app/assets/stylesheets/welcome.css.scss +0 -3
  84. data/guides/code/getting_started/app/controllers/application_controller.rb +0 -5
  85. data/guides/code/getting_started/app/controllers/comments_controller.rb +0 -23
  86. data/guides/code/getting_started/app/controllers/posts_controller.rb +0 -53
  87. data/guides/code/getting_started/app/controllers/welcome_controller.rb +0 -4
  88. data/guides/code/getting_started/app/helpers/application_helper.rb +0 -2
  89. data/guides/code/getting_started/app/helpers/comments_helper.rb +0 -2
  90. data/guides/code/getting_started/app/helpers/posts_helper.rb +0 -2
  91. data/guides/code/getting_started/app/helpers/welcome_helper.rb +0 -2
  92. data/guides/code/getting_started/app/models/comment.rb +0 -3
  93. data/guides/code/getting_started/app/models/post.rb +0 -7
  94. data/guides/code/getting_started/app/views/comments/_comment.html.erb +0 -15
  95. data/guides/code/getting_started/app/views/comments/_form.html.erb +0 -13
  96. data/guides/code/getting_started/app/views/layouts/application.html.erb +0 -14
  97. data/guides/code/getting_started/app/views/posts/_form.html.erb +0 -27
  98. data/guides/code/getting_started/app/views/posts/edit.html.erb +0 -5
  99. data/guides/code/getting_started/app/views/posts/index.html.erb +0 -21
  100. data/guides/code/getting_started/app/views/posts/new.html.erb +0 -5
  101. data/guides/code/getting_started/app/views/posts/show.html.erb +0 -18
  102. data/guides/code/getting_started/app/views/welcome/index.html.erb +0 -4
  103. data/guides/code/getting_started/bin/bundle +0 -4
  104. data/guides/code/getting_started/bin/rails +0 -4
  105. data/guides/code/getting_started/bin/rake +0 -4
  106. data/guides/code/getting_started/config/application.rb +0 -18
  107. data/guides/code/getting_started/config/boot.rb +0 -4
  108. data/guides/code/getting_started/config/database.yml +0 -25
  109. data/guides/code/getting_started/config/environment.rb +0 -5
  110. data/guides/code/getting_started/config/environments/development.rb +0 -30
  111. data/guides/code/getting_started/config/environments/production.rb +0 -80
  112. data/guides/code/getting_started/config/environments/test.rb +0 -36
  113. data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +0 -7
  114. data/guides/code/getting_started/config/initializers/filter_parameter_logging.rb +0 -4
  115. data/guides/code/getting_started/config/initializers/inflections.rb +0 -16
  116. data/guides/code/getting_started/config/initializers/locale.rb +0 -9
  117. data/guides/code/getting_started/config/initializers/mime_types.rb +0 -5
  118. data/guides/code/getting_started/config/initializers/secret_token.rb +0 -12
  119. data/guides/code/getting_started/config/initializers/session_store.rb +0 -3
  120. data/guides/code/getting_started/config/initializers/wrap_parameters.rb +0 -14
  121. data/guides/code/getting_started/config/locales/en.yml +0 -23
  122. data/guides/code/getting_started/config/routes.rb +0 -7
  123. data/guides/code/getting_started/config.ru +0 -4
  124. data/guides/code/getting_started/db/migrate/20130122042648_create_posts.rb +0 -10
  125. data/guides/code/getting_started/db/migrate/20130122045842_create_comments.rb +0 -11
  126. data/guides/code/getting_started/db/schema.rb +0 -33
  127. data/guides/code/getting_started/db/seeds.rb +0 -7
  128. data/guides/code/getting_started/public/404.html +0 -60
  129. data/guides/code/getting_started/public/422.html +0 -60
  130. data/guides/code/getting_started/public/500.html +0 -59
  131. data/guides/code/getting_started/public/favicon.ico +0 -0
  132. data/guides/code/getting_started/public/robots.txt +0 -5
  133. data/guides/code/getting_started/test/controllers/comments_controller_test.rb +0 -7
  134. data/guides/code/getting_started/test/controllers/posts_controller_test.rb +0 -7
  135. data/guides/code/getting_started/test/controllers/welcome_controller_test.rb +0 -9
  136. data/guides/code/getting_started/test/fixtures/comments.yml +0 -11
  137. data/guides/code/getting_started/test/fixtures/posts.yml +0 -9
  138. data/guides/code/getting_started/test/helpers/comments_helper_test.rb +0 -4
  139. data/guides/code/getting_started/test/helpers/posts_helper_test.rb +0 -4
  140. data/guides/code/getting_started/test/helpers/welcome_helper_test.rb +0 -4
  141. data/guides/code/getting_started/test/models/comment_test.rb +0 -7
  142. data/guides/code/getting_started/test/models/post_test.rb +0 -7
  143. data/guides/code/getting_started/test/test_helper.rb +0 -12
@@ -101,13 +101,13 @@ class CreateOrders < ActiveRecord::Migration
101
101
  def change
102
102
  create_table :customers do |t|
103
103
  t.string :name
104
- t.timestamps
104
+ t.timestamps null: false
105
105
  end
106
106
 
107
107
  create_table :orders do |t|
108
- t.belongs_to :customer
108
+ t.belongs_to :customer, index: true
109
109
  t.datetime :order_date
110
- t.timestamps
110
+ t.timestamps null: false
111
111
  end
112
112
  end
113
113
  end
@@ -132,13 +132,13 @@ class CreateSuppliers < ActiveRecord::Migration
132
132
  def change
133
133
  create_table :suppliers do |t|
134
134
  t.string :name
135
- t.timestamps
135
+ t.timestamps null: false
136
136
  end
137
137
 
138
138
  create_table :accounts do |t|
139
- t.belongs_to :supplier
139
+ t.belongs_to :supplier, index: true
140
140
  t.string :account_number
141
- t.timestamps
141
+ t.timestamps null: false
142
142
  end
143
143
  end
144
144
  end
@@ -165,13 +165,13 @@ class CreateCustomers < ActiveRecord::Migration
165
165
  def change
166
166
  create_table :customers do |t|
167
167
  t.string :name
168
- t.timestamps
168
+ t.timestamps null: false
169
169
  end
170
170
 
171
171
  create_table :orders do |t|
172
- t.belongs_to :customer
172
+ t.belongs_to :customer, index:true
173
173
  t.datetime :order_date
174
- t.timestamps
174
+ t.timestamps null: false
175
175
  end
176
176
  end
177
177
  end
@@ -207,19 +207,19 @@ class CreateAppointments < ActiveRecord::Migration
207
207
  def change
208
208
  create_table :physicians do |t|
209
209
  t.string :name
210
- t.timestamps
210
+ t.timestamps null: false
211
211
  end
212
212
 
213
213
  create_table :patients do |t|
214
214
  t.string :name
215
- t.timestamps
215
+ t.timestamps null: false
216
216
  end
217
217
 
218
218
  create_table :appointments do |t|
219
- t.belongs_to :physician
220
- t.belongs_to :patient
219
+ t.belongs_to :physician, index: true
220
+ t.belongs_to :patient, index: true
221
221
  t.datetime :appointment_date
222
- t.timestamps
222
+ t.timestamps null: false
223
223
  end
224
224
  end
225
225
  end
@@ -291,19 +291,19 @@ class CreateAccountHistories < ActiveRecord::Migration
291
291
  def change
292
292
  create_table :suppliers do |t|
293
293
  t.string :name
294
- t.timestamps
294
+ t.timestamps null: false
295
295
  end
296
296
 
297
297
  create_table :accounts do |t|
298
- t.belongs_to :supplier
298
+ t.belongs_to :supplier, index: true
299
299
  t.string :account_number
300
- t.timestamps
300
+ t.timestamps null: false
301
301
  end
302
302
 
303
303
  create_table :account_histories do |t|
304
- t.belongs_to :account
304
+ t.belongs_to :account, index: true
305
305
  t.integer :credit_rating
306
- t.timestamps
306
+ t.timestamps null: false
307
307
  end
308
308
  end
309
309
  end
@@ -332,17 +332,17 @@ class CreateAssembliesAndParts < ActiveRecord::Migration
332
332
  def change
333
333
  create_table :assemblies do |t|
334
334
  t.string :name
335
- t.timestamps
335
+ t.timestamps null: false
336
336
  end
337
337
 
338
338
  create_table :parts do |t|
339
339
  t.string :part_number
340
- t.timestamps
340
+ t.timestamps null: false
341
341
  end
342
342
 
343
343
  create_table :assemblies_parts, id: false do |t|
344
- t.belongs_to :assembly
345
- t.belongs_to :part
344
+ t.belongs_to :assembly, index: true
345
+ t.belongs_to :part, index: true
346
346
  end
347
347
  end
348
348
  end
@@ -371,14 +371,16 @@ class CreateSuppliers < ActiveRecord::Migration
371
371
  def change
372
372
  create_table :suppliers do |t|
373
373
  t.string :name
374
- t.timestamps
374
+ t.timestamps null: false
375
375
  end
376
376
 
377
377
  create_table :accounts do |t|
378
378
  t.integer :supplier_id
379
379
  t.string :account_number
380
- t.timestamps
380
+ t.timestamps null: false
381
381
  end
382
+
383
+ add_index :accounts, :supplier_id
382
384
  end
383
385
  end
384
386
  ```
@@ -453,8 +455,10 @@ class CreatePictures < ActiveRecord::Migration
453
455
  t.string :name
454
456
  t.integer :imageable_id
455
457
  t.string :imageable_type
456
- t.timestamps
458
+ t.timestamps null: false
457
459
  end
460
+
461
+ add_index :pictures, :imageable_id
458
462
  end
459
463
  end
460
464
  ```
@@ -466,8 +470,8 @@ class CreatePictures < ActiveRecord::Migration
466
470
  def change
467
471
  create_table :pictures do |t|
468
472
  t.string :name
469
- t.references :imageable, polymorphic: true
470
- t.timestamps
473
+ t.references :imageable, polymorphic: true, index: true
474
+ t.timestamps null: false
471
475
  end
472
476
  end
473
477
  end
@@ -496,8 +500,8 @@ In your migrations/schema, you will add a references column to the model itself.
496
500
  class CreateEmployees < ActiveRecord::Migration
497
501
  def change
498
502
  create_table :employees do |t|
499
- t.references :manager
500
- t.timestamps
503
+ t.references :manager, index: true
504
+ t.timestamps null: false
501
505
  end
502
506
  end
503
507
  end
@@ -561,6 +565,8 @@ class CreateOrders < ActiveRecord::Migration
561
565
  t.string :order_number
562
566
  t.integer :customer_id
563
567
  end
568
+
569
+ add_index :orders, :customer_id
564
570
  end
565
571
  end
566
572
  ```
@@ -571,7 +577,7 @@ If you create an association some time after you build the underlying model, you
571
577
 
572
578
  If you create a `has_and_belongs_to_many` association, you need to explicitly create the joining table. Unless the name of the join table is explicitly specified by using the `:join_table` option, Active Record creates the name by using the lexical order of the class names. So a join between customer and order models will give the default join table name of "customers_orders" because "c" outranks "o" in lexical ordering.
573
579
 
574
- WARNING: The precedence between model names is calculated using the `<` operator for `String`. This means that if the strings are of different lengths, and the strings are equal when compared up to the shortest length, then the longer string is considered of higher lexical precedence than the shorter one. For example, one would expect the tables "paper\_boxes" and "papers" to generate a join table name of "papers\_paper\_boxes" because of the length of the name "paper\_boxes", but it in fact generates a join table name of "paper\_boxes\_papers" (because the underscore '\_' is lexicographically _less_ than 's' in common encodings).
580
+ WARNING: The precedence between model names is calculated using the `<` operator for `String`. This means that if the strings are of different lengths, and the strings are equal when compared up to the shortest length, then the longer string is considered of higher lexical precedence than the shorter one. For example, one would expect the tables "paper_boxes" and "papers" to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes", but it in fact generates a join table name of "paper_boxes_papers" (because the underscore '_' is lexicographically _less_ than 's' in common encodings).
575
581
 
576
582
  Whatever the name, you must manually generate the join table with an appropriate migration. For example, consider these associations:
577
583
 
@@ -594,6 +600,9 @@ class CreateAssembliesPartsJoinTable < ActiveRecord::Migration
594
600
  t.integer :assembly_id
595
601
  t.integer :part_id
596
602
  end
603
+
604
+ add_index :assemblies_parts, :assembly_id
605
+ add_index :assemblies_parts, :part_id
597
606
  end
598
607
  end
599
608
  ```
@@ -747,7 +756,7 @@ class Order < ActiveRecord::Base
747
756
  end
748
757
  ```
749
758
 
750
- Each instance of the order model will have these methods:
759
+ Each instance of the `Order` model will have these methods:
751
760
 
752
761
  ```ruby
753
762
  customer
@@ -1131,7 +1140,7 @@ The `has_one` association supports these options:
1131
1140
 
1132
1141
  ##### `:as`
1133
1142
 
1134
- Setting the `:as` option indicates that this is a polymorphic association. Polymorphic associations were discussed in detail <a href="#polymorphic-associations">earlier in this guide</a>.
1143
+ Setting the `:as` option indicates that this is a polymorphic association. Polymorphic associations were discussed in detail [earlier in this guide](#polymorphic-associations).
1135
1144
 
1136
1145
  ##### `:autosave`
1137
1146
 
@@ -1203,7 +1212,7 @@ The `:source_type` option specifies the source association type for a `has_one :
1203
1212
 
1204
1213
  ##### `:through`
1205
1214
 
1206
- The `:through` option specifies a join model through which to perform the query. `has_one :through` associations were discussed in detail <a href="#the-has-one-through-association">earlier in this guide</a>.
1215
+ The `:through` option specifies a join model through which to perform the query. `has_one :through` associations were discussed in detail [earlier in this guide](#the-has-one-through-association).
1207
1216
 
1208
1217
  ##### `:validate`
1209
1218
 
@@ -1312,9 +1321,9 @@ When you declare a `has_many` association, the declaring class automatically gai
1312
1321
  * `collection<<(object, ...)`
1313
1322
  * `collection.delete(object, ...)`
1314
1323
  * `collection.destroy(object, ...)`
1315
- * `collection=objects`
1324
+ * `collection=(objects)`
1316
1325
  * `collection_singular_ids`
1317
- * `collection_singular_ids=ids`
1326
+ * `collection_singular_ids=(ids)`
1318
1327
  * `collection.clear`
1319
1328
  * `collection.empty?`
1320
1329
  * `collection.size`
@@ -1333,16 +1342,16 @@ class Customer < ActiveRecord::Base
1333
1342
  end
1334
1343
  ```
1335
1344
 
1336
- Each instance of the customer model will have these methods:
1345
+ Each instance of the `Customer` model will have these methods:
1337
1346
 
1338
1347
  ```ruby
1339
1348
  orders(force_reload = false)
1340
1349
  orders<<(object, ...)
1341
1350
  orders.delete(object, ...)
1342
1351
  orders.destroy(object, ...)
1343
- orders=objects
1352
+ orders=(objects)
1344
1353
  order_ids
1345
- order_ids=ids
1354
+ order_ids=(ids)
1346
1355
  orders.clear
1347
1356
  orders.empty?
1348
1357
  orders.size
@@ -1390,7 +1399,7 @@ The `collection.destroy` method removes one or more objects from the collection
1390
1399
 
1391
1400
  WARNING: Objects will _always_ be removed from the database, ignoring the `:dependent` option.
1392
1401
 
1393
- ##### `collection=objects`
1402
+ ##### `collection=(objects)`
1394
1403
 
1395
1404
  The `collection=` method makes the collection contain only the supplied objects, by adding and deleting as appropriate.
1396
1405
 
@@ -1402,7 +1411,7 @@ The `collection_singular_ids` method returns an array of the ids of the objects
1402
1411
  @order_ids = @customer.order_ids
1403
1412
  ```
1404
1413
 
1405
- ##### `collection_singular_ids=ids`
1414
+ ##### `collection_singular_ids=(ids)`
1406
1415
 
1407
1416
  The `collection_singular_ids=` method makes the collection contain only the objects identified by the supplied primary key values, by adding and deleting as appropriate.
1408
1417
 
@@ -1497,7 +1506,7 @@ The `has_many` association supports these options:
1497
1506
 
1498
1507
  ##### `:as`
1499
1508
 
1500
- Setting the `:as` option indicates that this is a polymorphic association, as discussed <a href="#polymorphic-associations">earlier in this guide</a>.
1509
+ Setting the `:as` option indicates that this is a polymorphic association, as discussed [earlier in this guide](#polymorphic-associations).
1501
1510
 
1502
1511
  ##### `:autosave`
1503
1512
 
@@ -1523,8 +1532,6 @@ Controls what happens to the associated objects when their owner is destroyed:
1523
1532
  * `:restrict_with_exception` causes an exception to be raised if there are any associated records
1524
1533
  * `:restrict_with_error` causes an error to be added to the owner if there are any associated objects
1525
1534
 
1526
- NOTE: This option is ignored when you use the `:through` option on the association.
1527
-
1528
1535
  ##### `:foreign_key`
1529
1536
 
1530
1537
  By convention, Rails assumes that the column used to hold the foreign key on the other model is the name of this model with the suffix `_id` added. The `:foreign_key` option lets you set the name of the foreign key directly:
@@ -1579,7 +1586,7 @@ The `:source_type` option specifies the source association type for a `has_many
1579
1586
 
1580
1587
  ##### `:through`
1581
1588
 
1582
- The `:through` option specifies a join model through which to perform the query. `has_many :through` associations provide a way to implement many-to-many relationships, as discussed <a href="#the-has-many-through-association">earlier in this guide</a>.
1589
+ The `:through` option specifies a join model through which to perform the query. `has_many :through` associations provide a way to implement many-to-many relationships, as discussed [earlier in this guide](#the-has-many-through-association).
1583
1590
 
1584
1591
  ##### `:validate`
1585
1592
 
@@ -1632,7 +1639,7 @@ If you use a hash-style `where` option, then record creation via this associatio
1632
1639
 
1633
1640
  ##### `extending`
1634
1641
 
1635
- The `extending` method specifies a named module to extend the association proxy. Association extensions are discussed in detail <a href="#association-extensions">later in this guide</a>.
1642
+ The `extending` method specifies a named module to extend the association proxy. Association extensions are discussed in detail [later in this guide](#association-extensions).
1636
1643
 
1637
1644
  ##### `group`
1638
1645
 
@@ -1725,58 +1732,58 @@ mostly useful together with the `:through` option.
1725
1732
  ```ruby
1726
1733
  class Person < ActiveRecord::Base
1727
1734
  has_many :readings
1728
- has_many :posts, through: :readings
1735
+ has_many :articles, through: :readings
1729
1736
  end
1730
1737
 
1731
1738
  person = Person.create(name: 'John')
1732
- post = Post.create(name: 'a1')
1733
- person.posts << post
1734
- person.posts << post
1735
- person.posts.inspect # => [#<Post id: 5, name: "a1">, #<Post id: 5, name: "a1">]
1736
- Reading.all.inspect # => [#<Reading id: 12, person_id: 5, post_id: 5>, #<Reading id: 13, person_id: 5, post_id: 5>]
1739
+ article = Article.create(name: 'a1')
1740
+ person.articles << article
1741
+ person.articles << article
1742
+ person.articles.inspect # => [#<Article id: 5, name: "a1">, #<Article id: 5, name: "a1">]
1743
+ Reading.all.inspect # => [#<Reading id: 12, person_id: 5, article_id: 5>, #<Reading id: 13, person_id: 5, article_id: 5>]
1737
1744
  ```
1738
1745
 
1739
- In the above case there are two readings and `person.posts` brings out both of
1740
- them even though these records are pointing to the same post.
1746
+ In the above case there are two readings and `person.articles` brings out both of
1747
+ them even though these records are pointing to the same article.
1741
1748
 
1742
1749
  Now let's set `distinct`:
1743
1750
 
1744
1751
  ```ruby
1745
1752
  class Person
1746
1753
  has_many :readings
1747
- has_many :posts, -> { distinct }, through: :readings
1754
+ has_many :articles, -> { distinct }, through: :readings
1748
1755
  end
1749
1756
 
1750
1757
  person = Person.create(name: 'Honda')
1751
- post = Post.create(name: 'a1')
1752
- person.posts << post
1753
- person.posts << post
1754
- person.posts.inspect # => [#<Post id: 7, name: "a1">]
1755
- Reading.all.inspect # => [#<Reading id: 16, person_id: 7, post_id: 7>, #<Reading id: 17, person_id: 7, post_id: 7>]
1758
+ article = Article.create(name: 'a1')
1759
+ person.articles << article
1760
+ person.articles << article
1761
+ person.articles.inspect # => [#<Article id: 7, name: "a1">]
1762
+ Reading.all.inspect # => [#<Reading id: 16, person_id: 7, article_id: 7>, #<Reading id: 17, person_id: 7, article_id: 7>]
1756
1763
  ```
1757
1764
 
1758
- In the above case there are still two readings. However `person.posts` shows
1759
- only one post because the collection loads only unique records.
1765
+ In the above case there are still two readings. However `person.articles` shows
1766
+ only one article because the collection loads only unique records.
1760
1767
 
1761
1768
  If you want to make sure that, upon insertion, all of the records in the
1762
1769
  persisted association are distinct (so that you can be sure that when you
1763
1770
  inspect the association that you will never find duplicate records), you should
1764
1771
  add a unique index on the table itself. For example, if you have a table named
1765
- `person_posts` and you want to make sure all the posts are unique, you could
1772
+ `person_articles` and you want to make sure all the articles are unique, you could
1766
1773
  add the following in a migration:
1767
1774
 
1768
1775
  ```ruby
1769
- add_index :person_posts, :post, unique: true
1776
+ add_index :person_articles, :article, unique: true
1770
1777
  ```
1771
1778
 
1772
1779
  Note that checking for uniqueness using something like `include?` is subject
1773
1780
  to race conditions. Do not attempt to use `include?` to enforce distinctness
1774
- in an association. For instance, using the post example from above, the
1781
+ in an association. For instance, using the article example from above, the
1775
1782
  following code would be racy because multiple users could be attempting this
1776
1783
  at the same time:
1777
1784
 
1778
1785
  ```ruby
1779
- person.posts << post unless person.posts.include?(post)
1786
+ person.articles << article unless person.articles.include?(article)
1780
1787
  ```
1781
1788
 
1782
1789
  #### When are Objects Saved?
@@ -1801,9 +1808,9 @@ When you declare a `has_and_belongs_to_many` association, the declaring class au
1801
1808
  * `collection<<(object, ...)`
1802
1809
  * `collection.delete(object, ...)`
1803
1810
  * `collection.destroy(object, ...)`
1804
- * `collection=objects`
1811
+ * `collection=(objects)`
1805
1812
  * `collection_singular_ids`
1806
- * `collection_singular_ids=ids`
1813
+ * `collection_singular_ids=(ids)`
1807
1814
  * `collection.clear`
1808
1815
  * `collection.empty?`
1809
1816
  * `collection.size`
@@ -1822,16 +1829,16 @@ class Part < ActiveRecord::Base
1822
1829
  end
1823
1830
  ```
1824
1831
 
1825
- Each instance of the part model will have these methods:
1832
+ Each instance of the `Part` model will have these methods:
1826
1833
 
1827
1834
  ```ruby
1828
1835
  assemblies(force_reload = false)
1829
1836
  assemblies<<(object, ...)
1830
1837
  assemblies.delete(object, ...)
1831
1838
  assemblies.destroy(object, ...)
1832
- assemblies=objects
1839
+ assemblies=(objects)
1833
1840
  assembly_ids
1834
- assembly_ids=ids
1841
+ assembly_ids=(ids)
1835
1842
  assemblies.clear
1836
1843
  assemblies.empty?
1837
1844
  assemblies.size
@@ -1886,7 +1893,7 @@ The `collection.destroy` method removes one or more objects from the collection
1886
1893
  @part.assemblies.destroy(@assembly1)
1887
1894
  ```
1888
1895
 
1889
- ##### `collection=objects`
1896
+ ##### `collection=(objects)`
1890
1897
 
1891
1898
  The `collection=` method makes the collection contain only the supplied objects, by adding and deleting as appropriate.
1892
1899
 
@@ -1898,7 +1905,7 @@ The `collection_singular_ids` method returns an array of the ids of the objects
1898
1905
  @assembly_ids = @part.assembly_ids
1899
1906
  ```
1900
1907
 
1901
- ##### `collection_singular_ids=ids`
1908
+ ##### `collection_singular_ids=(ids)`
1902
1909
 
1903
1910
  The `collection_singular_ids=` method makes the collection contain only the objects identified by the supplied primary key values, by adding and deleting as appropriate.
1904
1911
 
@@ -2082,7 +2089,7 @@ If you use a hash-style `where`, then record creation via this association will
2082
2089
 
2083
2090
  ##### `extending`
2084
2091
 
2085
- The `extending` method specifies a named module to extend the association proxy. Association extensions are discussed in detail <a href="#association-extensions">later in this guide</a>.
2092
+ The `extending` method specifies a named module to extend the association proxy. Association extensions are discussed in detail [later in this guide](#association-extensions).
2086
2093
 
2087
2094
  ##### `group`
2088
2095
 
@@ -28,15 +28,15 @@ config.action_controller.perform_caching = true
28
28
 
29
29
  ### Page Caching
30
30
 
31
- Page caching is a Rails mechanism which allows the request for a generated page to be fulfilled by the webserver (i.e. Apache or nginx), without ever having to go through the Rails stack at all. Obviously, this is super-fast. Unfortunately, it can't be applied to every situation (such as pages that need authentication) and since the webserver is literally just serving a file from the filesystem, cache expiration is an issue that needs to be dealt with.
31
+ Page caching is a Rails mechanism which allows the request for a generated page to be fulfilled by the webserver (i.e. Apache or NGINX), without ever having to go through the Rails stack at all. Obviously, this is super-fast. Unfortunately, it can't be applied to every situation (such as pages that need authentication) and since the webserver is literally just serving a file from the filesystem, cache expiration is an issue that needs to be dealt with.
32
32
 
33
- INFO: Page Caching has been removed from Rails 4. See the [actionpack-page_caching gem](https://github.com/rails/actionpack-page_caching). See [DHH's key-based cache expiration overview](http://37signals.com/svn/posts/3113-how-key-based-cache-expiration-works) for the newly-preferred method.
33
+ INFO: Page Caching has been removed from Rails 4. See the [actionpack-page_caching gem](https://github.com/rails/actionpack-page_caching). See [DHH's key-based cache expiration overview](http://signalvnoise.com/posts/3113-how-key-based-cache-expiration-works) for the newly-preferred method.
34
34
 
35
35
  ### Action Caching
36
36
 
37
37
  Page Caching cannot be used for actions that have before filters - for example, pages that require authentication. This is where Action Caching comes in. Action Caching works like Page Caching except the incoming web request hits the Rails stack so that before filters can be run on it before the cache is served. This allows authentication and other restrictions to be run while still serving the result of the output from a cached copy.
38
38
 
39
- INFO: Action Caching has been removed from Rails 4. See the [actionpack-action_caching gem](https://github.com/rails/actionpack-action_caching). See [DHH's key-based cache expiration overview](http://37signals.com/svn/posts/3113-how-key-based-cache-expiration-works) for the newly-preferred method.
39
+ INFO: Action Caching has been removed from Rails 4. See the [actionpack-action_caching gem](https://github.com/rails/actionpack-action_caching). See [DHH's key-based cache expiration overview](http://signalvnoise.com/posts/3113-how-key-based-cache-expiration-works) for the newly-preferred method.
40
40
 
41
41
  ### Fragment Caching
42
42
 
@@ -105,7 +105,7 @@ This method generates a cache key that depends on all products and can be used i
105
105
  <% end %>
106
106
  ```
107
107
 
108
- If you want to cache a fragment under certain condition you can use `cache_if` or `cache_unless`
108
+ If you want to cache a fragment under certain condition you can use `cache_if` or `cache_unless`
109
109
 
110
110
  ```erb
111
111
  <% cache_if (condition, cache_key_for_products) do %>
@@ -140,6 +140,26 @@ You can also combine the two schemes which is called "Russian Doll Caching":
140
140
 
141
141
  It's called "Russian Doll Caching" because it nests multiple fragments. The advantage is that if a single product is updated, all the other inner fragments can be reused when regenerating the outer fragment.
142
142
 
143
+ ### Low-Level Caching
144
+
145
+ Sometimes you need to cache a particular value or query result, instead of caching view fragments. Rails caching mechanism works great for storing __any__ kind of information.
146
+
147
+ The most efficient way to implement low-level caching is using the `Rails.cache.fetch` method. This method does both reading and writing to the cache. When passed only a single argument, the key is fetched and value from the cache is returned. If a block is passed, the result of the block will be cached to the given key and the result is returned.
148
+
149
+ Consider the following example. An application has a `Product` model with an instance method that looks up the product’s price on a competing website. The data returned by this method would be perfect for low-level caching:
150
+
151
+ ```ruby
152
+ class Product < ActiveRecord::Base
153
+ def competing_price
154
+ Rails.cache.fetch("#{cache_key}/competing_price", expires_in: 12.hours) do
155
+ Competitor::API.find_price(id)
156
+ end
157
+ end
158
+ end
159
+ ```
160
+
161
+ NOTE: Notice that in this example we used `cache_key` method, so the resulting cache-key will be something like `products/233-20140225082222765838000/competing_price`. `cache_key` generates a string based on the model’s `id` and `updated_at` attributes. This is a common convention and has the benefit of invalidating the cache whenever the product is updated. In general, when you use low-level caching for instance level information, you need to generate a cache key.
162
+
143
163
  ### SQL Caching
144
164
 
145
165
  Query caching is a Rails feature that caches the result set returned by each query so that if Rails encounters the same query again for that request, it will use the cached result set as opposed to running the query against the database again.
@@ -165,7 +185,7 @@ end
165
185
  Cache Stores
166
186
  ------------
167
187
 
168
- Rails provides different stores for the cached data created by <b>action</b> and <b>fragment</b> caches.
188
+ Rails provides different stores for the cached data created by **action** and **fragment** caches.
169
189
 
170
190
  TIP: Page caches are always stored on disk.
171
191
 
@@ -333,12 +353,17 @@ Instead of an options hash, you can also simply pass in a model, Rails will use
333
353
  class ProductsController < ApplicationController
334
354
  def show
335
355
  @product = Product.find(params[:id])
336
- respond_with(@product) if stale?(@product)
356
+
357
+ if stale?(@product)
358
+ respond_to do |wants|
359
+ # ... normal response processing
360
+ end
361
+ end
337
362
  end
338
363
  end
339
364
  ```
340
365
 
341
- If you don't have any special response processing and are using the default rendering mechanism (i.e. you're not using respond_to or calling render yourself) then you've got an easy helper in fresh_when:
366
+ If you don't have any special response processing and are using the default rendering mechanism (i.e. you're not using `respond_to` or calling render yourself) then you've got an easy helper in `fresh_when`:
342
367
 
343
368
  ```ruby
344
369
  class ProductsController < ApplicationController