rails 4.1.4 → 4.2.11.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +12 -10
  3. data/guides/CHANGELOG.md +87 -15
  4. data/guides/Rakefile +21 -6
  5. data/guides/assets/images/getting_started/article_with_comments.png +0 -0
  6. data/guides/assets/javascripts/guides.js +6 -0
  7. data/guides/assets/stylesheets/main.css +4 -1
  8. data/guides/bug_report_templates/action_controller_gem.rb +3 -3
  9. data/guides/bug_report_templates/action_controller_master.rb +3 -2
  10. data/guides/bug_report_templates/active_record_gem.rb +1 -1
  11. data/guides/bug_report_templates/generic_gem.rb +15 -0
  12. data/guides/bug_report_templates/generic_master.rb +26 -0
  13. data/guides/rails_guides/helpers.rb +1 -1
  14. data/guides/rails_guides/levenshtein.rb +27 -21
  15. data/guides/rails_guides/markdown/renderer.rb +1 -1
  16. data/guides/rails_guides/markdown.rb +11 -7
  17. data/guides/rails_guides.rb +2 -2
  18. data/guides/source/2_2_release_notes.md +1 -1
  19. data/guides/source/2_3_release_notes.md +4 -4
  20. data/guides/source/3_0_release_notes.md +8 -8
  21. data/guides/source/3_1_release_notes.md +6 -3
  22. data/guides/source/3_2_release_notes.md +6 -3
  23. data/guides/source/4_0_release_notes.md +6 -3
  24. data/guides/source/4_1_release_notes.md +10 -11
  25. data/guides/source/4_2_release_notes.md +877 -0
  26. data/guides/source/_license.html.erb +1 -1
  27. data/guides/source/_welcome.html.erb +6 -8
  28. data/guides/source/action_controller_overview.md +28 -11
  29. data/guides/source/action_mailer_basics.md +97 -29
  30. data/guides/source/action_view_overview.md +142 -191
  31. data/guides/source/active_job_basics.md +339 -0
  32. data/guides/source/active_model_basics.md +371 -17
  33. data/guides/source/active_record_basics.md +25 -24
  34. data/guides/source/active_record_callbacks.md +12 -9
  35. data/guides/source/{migrations.md → active_record_migrations.md} +135 -226
  36. data/guides/source/active_record_postgresql.md +433 -0
  37. data/guides/source/active_record_querying.md +270 -262
  38. data/guides/source/active_record_validations.md +24 -14
  39. data/guides/source/active_support_core_extensions.md +115 -123
  40. data/guides/source/active_support_instrumentation.md +10 -18
  41. data/guides/source/api_documentation_guidelines.md +63 -17
  42. data/guides/source/asset_pipeline.md +266 -125
  43. data/guides/source/association_basics.md +96 -80
  44. data/guides/source/autoloading_and_reloading_constants.md +1311 -0
  45. data/guides/source/caching_with_rails.md +32 -7
  46. data/guides/source/command_line.md +52 -30
  47. data/guides/source/configuring.md +161 -33
  48. data/guides/source/contributing_to_ruby_on_rails.md +198 -114
  49. data/guides/source/credits.html.erb +2 -2
  50. data/guides/source/debugging_rails_applications.md +448 -294
  51. data/guides/source/development_dependencies_install.md +47 -36
  52. data/guides/source/documents.yaml +19 -7
  53. data/guides/source/engines.md +217 -196
  54. data/guides/source/form_helpers.md +79 -56
  55. data/guides/source/generators.md +24 -11
  56. data/guides/source/getting_started.md +361 -222
  57. data/guides/source/i18n.md +113 -69
  58. data/guides/source/index.html.erb +1 -0
  59. data/guides/source/initialization.md +110 -63
  60. data/guides/source/layout.html.erb +5 -11
  61. data/guides/source/layouts_and_rendering.md +26 -26
  62. data/guides/source/maintenance_policy.md +26 -4
  63. data/guides/source/nested_model_forms.md +7 -4
  64. data/guides/source/plugins.md +27 -27
  65. data/guides/source/rails_application_templates.md +21 -3
  66. data/guides/source/rails_on_rack.md +12 -10
  67. data/guides/source/routing.md +115 -75
  68. data/guides/source/ruby_on_rails_guides_guidelines.md +11 -12
  69. data/guides/source/security.md +41 -35
  70. data/guides/source/testing.md +199 -119
  71. data/guides/source/upgrading_ruby_on_rails.md +319 -32
  72. data/guides/source/working_with_javascript_in_rails.md +19 -17
  73. data/guides/w3c_validator.rb +2 -0
  74. metadata +42 -95
  75. data/guides/code/getting_started/Gemfile +0 -40
  76. data/guides/code/getting_started/Gemfile.lock +0 -125
  77. data/guides/code/getting_started/README.rdoc +0 -28
  78. data/guides/code/getting_started/Rakefile +0 -6
  79. data/guides/code/getting_started/app/assets/javascripts/application.js +0 -15
  80. data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +0 -3
  81. data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +0 -3
  82. data/guides/code/getting_started/app/assets/javascripts/welcome.js.coffee +0 -3
  83. data/guides/code/getting_started/app/assets/stylesheets/application.css +0 -13
  84. data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +0 -3
  85. data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +0 -3
  86. data/guides/code/getting_started/app/assets/stylesheets/welcome.css.scss +0 -3
  87. data/guides/code/getting_started/app/controllers/application_controller.rb +0 -5
  88. data/guides/code/getting_started/app/controllers/comments_controller.rb +0 -23
  89. data/guides/code/getting_started/app/controllers/posts_controller.rb +0 -53
  90. data/guides/code/getting_started/app/controllers/welcome_controller.rb +0 -4
  91. data/guides/code/getting_started/app/helpers/application_helper.rb +0 -2
  92. data/guides/code/getting_started/app/helpers/comments_helper.rb +0 -2
  93. data/guides/code/getting_started/app/helpers/posts_helper.rb +0 -2
  94. data/guides/code/getting_started/app/helpers/welcome_helper.rb +0 -2
  95. data/guides/code/getting_started/app/models/comment.rb +0 -3
  96. data/guides/code/getting_started/app/models/post.rb +0 -7
  97. data/guides/code/getting_started/app/views/comments/_comment.html.erb +0 -15
  98. data/guides/code/getting_started/app/views/comments/_form.html.erb +0 -13
  99. data/guides/code/getting_started/app/views/layouts/application.html.erb +0 -14
  100. data/guides/code/getting_started/app/views/posts/_form.html.erb +0 -27
  101. data/guides/code/getting_started/app/views/posts/edit.html.erb +0 -5
  102. data/guides/code/getting_started/app/views/posts/index.html.erb +0 -21
  103. data/guides/code/getting_started/app/views/posts/new.html.erb +0 -5
  104. data/guides/code/getting_started/app/views/posts/show.html.erb +0 -18
  105. data/guides/code/getting_started/app/views/welcome/index.html.erb +0 -4
  106. data/guides/code/getting_started/bin/bundle +0 -4
  107. data/guides/code/getting_started/bin/rails +0 -4
  108. data/guides/code/getting_started/bin/rake +0 -4
  109. data/guides/code/getting_started/config/application.rb +0 -18
  110. data/guides/code/getting_started/config/boot.rb +0 -4
  111. data/guides/code/getting_started/config/database.yml +0 -25
  112. data/guides/code/getting_started/config/environment.rb +0 -5
  113. data/guides/code/getting_started/config/environments/development.rb +0 -30
  114. data/guides/code/getting_started/config/environments/production.rb +0 -80
  115. data/guides/code/getting_started/config/environments/test.rb +0 -36
  116. data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +0 -7
  117. data/guides/code/getting_started/config/initializers/filter_parameter_logging.rb +0 -4
  118. data/guides/code/getting_started/config/initializers/inflections.rb +0 -16
  119. data/guides/code/getting_started/config/initializers/locale.rb +0 -9
  120. data/guides/code/getting_started/config/initializers/mime_types.rb +0 -5
  121. data/guides/code/getting_started/config/initializers/secret_token.rb +0 -12
  122. data/guides/code/getting_started/config/initializers/session_store.rb +0 -3
  123. data/guides/code/getting_started/config/initializers/wrap_parameters.rb +0 -14
  124. data/guides/code/getting_started/config/locales/en.yml +0 -23
  125. data/guides/code/getting_started/config/routes.rb +0 -7
  126. data/guides/code/getting_started/config.ru +0 -4
  127. data/guides/code/getting_started/db/migrate/20130122042648_create_posts.rb +0 -10
  128. data/guides/code/getting_started/db/migrate/20130122045842_create_comments.rb +0 -11
  129. data/guides/code/getting_started/db/schema.rb +0 -33
  130. data/guides/code/getting_started/db/seeds.rb +0 -7
  131. data/guides/code/getting_started/public/404.html +0 -60
  132. data/guides/code/getting_started/public/422.html +0 -60
  133. data/guides/code/getting_started/public/500.html +0 -59
  134. data/guides/code/getting_started/public/favicon.ico +0 -0
  135. data/guides/code/getting_started/public/robots.txt +0 -5
  136. data/guides/code/getting_started/test/controllers/comments_controller_test.rb +0 -7
  137. data/guides/code/getting_started/test/controllers/posts_controller_test.rb +0 -7
  138. data/guides/code/getting_started/test/controllers/welcome_controller_test.rb +0 -9
  139. data/guides/code/getting_started/test/fixtures/comments.yml +0 -11
  140. data/guides/code/getting_started/test/fixtures/posts.yml +0 -9
  141. data/guides/code/getting_started/test/helpers/comments_helper_test.rb +0 -4
  142. data/guides/code/getting_started/test/helpers/posts_helper_test.rb +0 -4
  143. data/guides/code/getting_started/test/helpers/welcome_helper_test.rb +0 -4
  144. data/guides/code/getting_started/test/models/comment_test.rb +0 -7
  145. data/guides/code/getting_started/test/models/post_test.rb +0 -7
  146. data/guides/code/getting_started/test/test_helper.rb +0 -12
@@ -93,9 +93,9 @@ The primary operation of `Model.find(options)` can be summarized as:
93
93
 
94
94
  Active Record provides several different ways of retrieving a single object.
95
95
 
96
- #### Using a Primary Key
96
+ #### `find`
97
97
 
98
- Using `Model.find(primary_key)`, you can retrieve the object corresponding to the specified _primary key_ that matches any supplied options. For example:
98
+ Using the `find` method, you can retrieve the object corresponding to the specified _primary key_ that matches any supplied options. For example:
99
99
 
100
100
  ```ruby
101
101
  # Find the client with primary key (id) 10.
@@ -109,119 +109,103 @@ The SQL equivalent of the above is:
109
109
  SELECT * FROM clients WHERE (clients.id = 10) LIMIT 1
110
110
  ```
111
111
 
112
- `Model.find(primary_key)` will raise an `ActiveRecord::RecordNotFound` exception if no matching record is found.
112
+ The `find` method will raise an `ActiveRecord::RecordNotFound` exception if no matching record is found.
113
113
 
114
- #### `take`
115
-
116
- `Model.take` retrieves a record without any implicit ordering. For example:
114
+ You can also use this method to query for multiple objects. Call the `find` method and pass in an array of primary keys. The return will be an array containing all of the matching records for the supplied _primary keys_. For example:
117
115
 
118
116
  ```ruby
119
- client = Client.take
120
- # => #<Client id: 1, first_name: "Lifo">
117
+ # Find the clients with primary keys 1 and 10.
118
+ client = Client.find([1, 10]) # Or even Client.find(1, 10)
119
+ # => [#<Client id: 1, first_name: "Lifo">, #<Client id: 10, first_name: "Ryan">]
121
120
  ```
122
121
 
123
122
  The SQL equivalent of the above is:
124
123
 
125
124
  ```sql
126
- SELECT * FROM clients LIMIT 1
125
+ SELECT * FROM clients WHERE (clients.id IN (1,10))
127
126
  ```
128
127
 
129
- `Model.take` returns `nil` if no record is found and no exception will be raised.
128
+ WARNING: The `find` method will raise an `ActiveRecord::RecordNotFound` exception unless a matching record is found for **all** of the supplied primary keys.
130
129
 
131
- TIP: The retrieved record may vary depending on the database engine.
132
-
133
- #### `first`
130
+ #### `take`
134
131
 
135
- `Model.first` finds the first record ordered by the primary key. For example:
132
+ The `take` method retrieves a record without any implicit ordering. For example:
136
133
 
137
134
  ```ruby
138
- client = Client.first
135
+ client = Client.take
139
136
  # => #<Client id: 1, first_name: "Lifo">
140
137
  ```
141
138
 
142
139
  The SQL equivalent of the above is:
143
140
 
144
141
  ```sql
145
- SELECT * FROM clients ORDER BY clients.id ASC LIMIT 1
142
+ SELECT * FROM clients LIMIT 1
146
143
  ```
147
144
 
148
- `Model.first` returns `nil` if no matching record is found and no exception will be raised.
145
+ The `take` method returns `nil` if no record is found and no exception will be raised.
149
146
 
150
- #### `last`
151
-
152
- `Model.last` finds the last record ordered by the primary key. For example:
147
+ You can pass in a numerical argument to the `take` method to return up to that number of results. For example
153
148
 
154
149
  ```ruby
155
- client = Client.last
156
- # => #<Client id: 221, first_name: "Russel">
150
+ client = Client.take(2)
151
+ # => [
152
+ #<Client id: 1, first_name: "Lifo">,
153
+ #<Client id: 220, first_name: "Sara">
154
+ ]
157
155
  ```
158
156
 
159
157
  The SQL equivalent of the above is:
160
158
 
161
159
  ```sql
162
- SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1
163
- ```
164
-
165
- `Model.last` returns `nil` if no matching record is found and no exception will be raised.
166
-
167
- #### `find_by`
168
-
169
- `Model.find_by` finds the first record matching some conditions. For example:
170
-
171
- ```ruby
172
- Client.find_by first_name: 'Lifo'
173
- # => #<Client id: 1, first_name: "Lifo">
174
-
175
- Client.find_by first_name: 'Jon'
176
- # => nil
160
+ SELECT * FROM clients LIMIT 2
177
161
  ```
178
162
 
179
- It is equivalent to writing:
163
+ The `take!` method behaves exactly like `take`, except that it will raise `ActiveRecord::RecordNotFound` if no matching record is found.
180
164
 
181
- ```ruby
182
- Client.where(first_name: 'Lifo').take
183
- ```
165
+ TIP: The retrieved record may vary depending on the database engine.
184
166
 
185
- #### `take!`
167
+ #### `first`
186
168
 
187
- `Model.take!` retrieves a record without any implicit ordering. For example:
169
+ The `first` method finds the first record ordered by the primary key. For example:
188
170
 
189
171
  ```ruby
190
- client = Client.take!
172
+ client = Client.first
191
173
  # => #<Client id: 1, first_name: "Lifo">
192
174
  ```
193
175
 
194
176
  The SQL equivalent of the above is:
195
177
 
196
178
  ```sql
197
- SELECT * FROM clients LIMIT 1
179
+ SELECT * FROM clients ORDER BY clients.id ASC LIMIT 1
198
180
  ```
199
181
 
200
- `Model.take!` raises `ActiveRecord::RecordNotFound` if no matching record is found.
201
-
202
- #### `first!`
182
+ The `first` method returns `nil` if no matching record is found and no exception will be raised.
203
183
 
204
- `Model.first!` finds the first record ordered by the primary key. For example:
184
+ You can pass in a numerical argument to the `first` method to return up to that number of results. For example
205
185
 
206
186
  ```ruby
207
- client = Client.first!
208
- # => #<Client id: 1, first_name: "Lifo">
187
+ client = Client.first(3)
188
+ # => [
189
+ #<Client id: 1, first_name: "Lifo">,
190
+ #<Client id: 2, first_name: "Fifo">,
191
+ #<Client id: 3, first_name: "Filo">
192
+ ]
209
193
  ```
210
194
 
211
195
  The SQL equivalent of the above is:
212
196
 
213
197
  ```sql
214
- SELECT * FROM clients ORDER BY clients.id ASC LIMIT 1
198
+ SELECT * FROM clients ORDER BY clients.id ASC LIMIT 3
215
199
  ```
216
200
 
217
- `Model.first!` raises `ActiveRecord::RecordNotFound` if no matching record is found.
201
+ The `first!` method behaves exactly like `first`, except that it will raise `ActiveRecord::RecordNotFound` if no matching record is found.
218
202
 
219
- #### `last!`
203
+ #### `last`
220
204
 
221
- `Model.last!` finds the last record ordered by the primary key. For example:
205
+ The `last` method finds the last record ordered by the primary key. For example:
222
206
 
223
207
  ```ruby
224
- client = Client.last!
208
+ client = Client.last
225
209
  # => #<Client id: 221, first_name: "Russel">
226
210
  ```
227
211
 
@@ -231,92 +215,56 @@ The SQL equivalent of the above is:
231
215
  SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1
232
216
  ```
233
217
 
234
- `Model.last!` raises `ActiveRecord::RecordNotFound` if no matching record is found.
235
-
236
- #### `find_by!`
237
-
238
- `Model.find_by!` finds the first record matching some conditions. It raises `ActiveRecord::RecordNotFound` if no matching record is found. For example:
239
-
240
- ```ruby
241
- Client.find_by! first_name: 'Lifo'
242
- # => #<Client id: 1, first_name: "Lifo">
243
-
244
- Client.find_by! first_name: 'Jon'
245
- # => ActiveRecord::RecordNotFound
246
- ```
247
-
248
- It is equivalent to writing:
249
-
250
- ```ruby
251
- Client.where(first_name: 'Lifo').take!
252
- ```
218
+ The `last` method returns `nil` if no matching record is found and no exception will be raised.
253
219
 
254
- ### Retrieving Multiple Objects
255
-
256
- #### Using Multiple Primary Keys
257
-
258
- `Model.find(array_of_primary_key)` accepts an array of _primary keys_, returning an array containing all of the matching records for the supplied _primary keys_. For example:
220
+ You can pass in a numerical argument to the `last` method to return up to that number of results. For example
259
221
 
260
222
  ```ruby
261
- # Find the clients with primary keys 1 and 10.
262
- client = Client.find([1, 10]) # Or even Client.find(1, 10)
263
- # => [#<Client id: 1, first_name: "Lifo">, #<Client id: 10, first_name: "Ryan">]
223
+ client = Client.last(3)
224
+ # => [
225
+ #<Client id: 219, first_name: "James">,
226
+ #<Client id: 220, first_name: "Sara">,
227
+ #<Client id: 221, first_name: "Russel">
228
+ ]
264
229
  ```
265
230
 
266
231
  The SQL equivalent of the above is:
267
232
 
268
233
  ```sql
269
- SELECT * FROM clients WHERE (clients.id IN (1,10))
234
+ SELECT * FROM clients ORDER BY clients.id DESC LIMIT 3
270
235
  ```
271
236
 
272
- WARNING: `Model.find(array_of_primary_key)` will raise an `ActiveRecord::RecordNotFound` exception unless a matching record is found for **all** of the supplied primary keys.
237
+ The `last!` method behaves exactly like `last`, except that it will raise `ActiveRecord::RecordNotFound` if no matching record is found.
273
238
 
274
- #### take
239
+ #### `find_by`
275
240
 
276
- `Model.take(limit)` retrieves the first number of records specified by `limit` without any explicit ordering:
241
+ The `find_by` method finds the first record matching some conditions. For example:
277
242
 
278
243
  ```ruby
279
- Client.take(2)
280
- # => [#<Client id: 1, first_name: "Lifo">,
281
- #<Client id: 2, first_name: "Raf">]
282
- ```
283
-
284
- The SQL equivalent of the above is:
244
+ Client.find_by first_name: 'Lifo'
245
+ # => #<Client id: 1, first_name: "Lifo">
285
246
 
286
- ```sql
287
- SELECT * FROM clients LIMIT 2
247
+ Client.find_by first_name: 'Jon'
248
+ # => nil
288
249
  ```
289
250
 
290
- #### first
291
-
292
- `Model.first(limit)` finds the first number of records specified by `limit` ordered by primary key:
251
+ It is equivalent to writing:
293
252
 
294
253
  ```ruby
295
- Client.first(2)
296
- # => [#<Client id: 1, first_name: "Lifo">,
297
- #<Client id: 2, first_name: "Raf">]
298
- ```
299
-
300
- The SQL equivalent of the above is:
301
-
302
- ```sql
303
- SELECT * FROM clients ORDER BY id ASC LIMIT 2
254
+ Client.where(first_name: 'Lifo').take
304
255
  ```
305
256
 
306
- #### last
307
-
308
- `Model.last(limit)` finds the number of records specified by `limit` ordered by primary key in descending order:
257
+ The `find_by!` method behaves exactly like `find_by`, except that it will raise `ActiveRecord::RecordNotFound` if no matching record is found. For example:
309
258
 
310
259
  ```ruby
311
- Client.last(2)
312
- # => [#<Client id: 10, first_name: "Ryan">,
313
- #<Client id: 9, first_name: "John">]
260
+ Client.find_by! first_name: 'does not exist'
261
+ # => ActiveRecord::RecordNotFound
314
262
  ```
315
263
 
316
- The SQL equivalent of the above is:
264
+ This is equivalent to writing:
317
265
 
318
- ```sql
319
- SELECT * FROM clients ORDER BY id DESC LIMIT 2
266
+ ```ruby
267
+ Client.where(first_name: 'does not exist').take!
320
268
  ```
321
269
 
322
270
  ### Retrieving Multiple Objects in Batches
@@ -328,7 +276,7 @@ This may appear straightforward:
328
276
  ```ruby
329
277
  # This is very inefficient when the users table has thousands of rows.
330
278
  User.all.each do |user|
331
- NewsLetter.weekly_deliver(user)
279
+ NewsMailer.weekly(user).deliver_now
332
280
  end
333
281
  ```
334
282
 
@@ -344,7 +292,15 @@ The `find_each` method retrieves a batch of records and then yields _each_ recor
344
292
 
345
293
  ```ruby
346
294
  User.find_each do |user|
347
- NewsLetter.weekly_deliver(user)
295
+ NewsMailer.weekly(user).deliver_now
296
+ end
297
+ ```
298
+
299
+ To add conditions to a `find_each` operation you can chain other Active Record methods such as `where`:
300
+
301
+ ```ruby
302
+ User.where(weekly_subscriber: true).find_each do |user|
303
+ NewsMailer.weekly(user).deliver_now
348
304
  end
349
305
  ```
350
306
 
@@ -360,7 +316,7 @@ The `:batch_size` option allows you to specify the number of records to be retri
360
316
 
361
317
  ```ruby
362
318
  User.find_each(batch_size: 5000) do |user|
363
- NewsLetter.weekly_deliver(user)
319
+ NewsMailer.weekly(user).deliver_now
364
320
  end
365
321
  ```
366
322
 
@@ -372,28 +328,24 @@ For example, to send newsletters only to users with the primary key starting fro
372
328
 
373
329
  ```ruby
374
330
  User.find_each(start: 2000, batch_size: 5000) do |user|
375
- NewsLetter.weekly_deliver(user)
331
+ NewsMailer.weekly(user).deliver_now
376
332
  end
377
333
  ```
378
334
 
379
- Another example would be if you wanted multiple workers handling the same processing queue. You could have each worker handle 10000 records by setting the appropriate `:start` option on each worker.
380
-
381
335
  #### `find_in_batches`
382
336
 
383
337
  The `find_in_batches` method is similar to `find_each`, since both retrieve batches of records. The difference is that `find_in_batches` yields _batches_ to the block as an array of models, instead of individually. The following example will yield to the supplied block an array of up to 1000 invoices at a time, with the final block containing any remaining invoices:
384
338
 
385
339
  ```ruby
386
340
  # Give add_invoices an array of 1000 invoices at a time
387
- Invoice.find_in_batches(include: :invoice_lines) do |invoices|
341
+ Invoice.find_in_batches do |invoices|
388
342
  export.add_invoices(invoices)
389
343
  end
390
344
  ```
391
345
 
392
- NOTE: The `:include` option allows you to name associations that should be loaded alongside with the models.
393
-
394
346
  ##### Options for `find_in_batches`
395
347
 
396
- The `find_in_batches` method accepts the same `:batch_size` and `:start` options as `find_each`, as well as most of the options allowed by the regular `find` method, except for `:order` and `:limit`, which are reserved for internal use by `find_in_batches`.
348
+ The `find_in_batches` method accepts the same `:batch_size` and `:start` options as `find_each`.
397
349
 
398
350
  Conditions
399
351
  ----------
@@ -472,8 +424,8 @@ Client.where('locked' => true)
472
424
  In the case of a belongs_to relationship, an association key can be used to specify the model if an Active Record object is used as the value. This method works with polymorphic relationships as well.
473
425
 
474
426
  ```ruby
475
- Post.where(author: author)
476
- Author.joins(:posts).where(posts: { author: author })
427
+ Article.where(author: author)
428
+ Author.joins(:articles).where(articles: { author: author })
477
429
  ```
478
430
 
479
431
  NOTE: The values cannot be symbols. For example, you cannot do `Client.where(status: :active)`.
@@ -511,7 +463,7 @@ SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5))
511
463
  `NOT` SQL queries can be built by `where.not`.
512
464
 
513
465
  ```ruby
514
- Post.where.not(author: author)
466
+ Article.where.not(author: author)
515
467
  ```
516
468
 
517
469
  In other words, this query can be generated by calling `where` with no argument, then immediately chain with `not` passing `where` conditions.
@@ -659,6 +611,23 @@ FROM orders
659
611
  GROUP BY date(created_at)
660
612
  ```
661
613
 
614
+ ### Total of grouped items
615
+
616
+ To get the total of grouped items on a single query call `count` after the `group`.
617
+
618
+ ```ruby
619
+ Order.group(:status).count
620
+ # => { 'awaiting_approval' => 7, 'paid' => 12 }
621
+ ```
622
+
623
+ The SQL that would be executed would be something like this:
624
+
625
+ ```sql
626
+ SELECT COUNT (*) AS count_all, status AS status
627
+ FROM "orders"
628
+ GROUP BY status
629
+ ```
630
+
662
631
  Having
663
632
  ------
664
633
 
@@ -690,32 +659,32 @@ Overriding Conditions
690
659
  You can specify certain conditions to be removed using the `unscope` method. For example:
691
660
 
692
661
  ```ruby
693
- Post.where('id > 10').limit(20).order('id asc').except(:order)
662
+ Article.where('id > 10').limit(20).order('id asc').unscope(:order)
694
663
  ```
695
664
 
696
665
  The SQL that would be executed:
697
666
 
698
667
  ```sql
699
- SELECT * FROM posts WHERE id > 10 LIMIT 20
668
+ SELECT * FROM articles WHERE id > 10 LIMIT 20
700
669
 
701
670
  # Original query without `unscope`
702
- SELECT * FROM posts WHERE id > 10 ORDER BY id asc LIMIT 20
671
+ SELECT * FROM articles WHERE id > 10 ORDER BY id asc LIMIT 20
703
672
 
704
673
  ```
705
674
 
706
- You can additionally unscope specific where clauses. For example:
675
+ You can also unscope specific `where` clauses. For example:
707
676
 
708
677
  ```ruby
709
- Post.where(id: 10, trashed: false).unscope(where: :id)
710
- # SELECT "posts".* FROM "posts" WHERE trashed = 0
678
+ Article.where(id: 10, trashed: false).unscope(where: :id)
679
+ # SELECT "articles".* FROM "articles" WHERE trashed = 0
711
680
  ```
712
681
 
713
682
  A relation which has used `unscope` will affect any relation it is
714
683
  merged in to:
715
684
 
716
685
  ```ruby
717
- Post.order('id asc').merge(Post.unscope(:order))
718
- # SELECT "posts".* FROM "posts"
686
+ Article.order('id asc').merge(Article.unscope(:order))
687
+ # SELECT "articles".* FROM "articles"
719
688
  ```
720
689
 
721
690
  ### `only`
@@ -723,16 +692,16 @@ Post.order('id asc').merge(Post.unscope(:order))
723
692
  You can also override conditions using the `only` method. For example:
724
693
 
725
694
  ```ruby
726
- Post.where('id > 10').limit(20).order('id desc').only(:order, :where)
695
+ Article.where('id > 10').limit(20).order('id desc').only(:order, :where)
727
696
  ```
728
697
 
729
698
  The SQL that would be executed:
730
699
 
731
700
  ```sql
732
- SELECT * FROM posts WHERE id > 10 ORDER BY id DESC
701
+ SELECT * FROM articles WHERE id > 10 ORDER BY id DESC
733
702
 
734
703
  # Original query without `only`
735
- SELECT "posts".* FROM "posts" WHERE (id > 10) ORDER BY id desc LIMIT 20
704
+ SELECT "articles".* FROM "articles" WHERE (id > 10) ORDER BY id desc LIMIT 20
736
705
 
737
706
  ```
738
707
 
@@ -741,26 +710,24 @@ SELECT "posts".* FROM "posts" WHERE (id > 10) ORDER BY id desc LIMIT 20
741
710
  The `reorder` method overrides the default scope order. For example:
742
711
 
743
712
  ```ruby
744
- class Post < ActiveRecord::Base
745
- ..
746
- ..
713
+ class Article < ActiveRecord::Base
747
714
  has_many :comments, -> { order('posted_at DESC') }
748
715
  end
749
716
 
750
- Post.find(10).comments.reorder('name')
717
+ Article.find(10).comments.reorder('name')
751
718
  ```
752
719
 
753
720
  The SQL that would be executed:
754
721
 
755
722
  ```sql
756
- SELECT * FROM posts WHERE id = 10
723
+ SELECT * FROM articles WHERE id = 10
757
724
  SELECT * FROM comments WHERE article_id = 10 ORDER BY name
758
725
  ```
759
726
 
760
727
  In case the `reorder` clause is not used, the SQL executed would be:
761
728
 
762
729
  ```sql
763
- SELECT * FROM posts WHERE id = 10
730
+ SELECT * FROM articles WHERE id = 10
764
731
  SELECT * FROM comments WHERE article_id = 10 ORDER BY posted_at DESC
765
732
  ```
766
733
 
@@ -797,25 +764,25 @@ This method accepts **no** arguments.
797
764
  The `rewhere` method overrides an existing, named where condition. For example:
798
765
 
799
766
  ```ruby
800
- Post.where(trashed: true).rewhere(trashed: false)
767
+ Article.where(trashed: true).rewhere(trashed: false)
801
768
  ```
802
769
 
803
770
  The SQL that would be executed:
804
771
 
805
772
  ```sql
806
- SELECT * FROM posts WHERE `trashed` = 0
773
+ SELECT * FROM articles WHERE `trashed` = 0
807
774
  ```
808
775
 
809
776
  In case the `rewhere` clause is not used,
810
777
 
811
778
  ```ruby
812
- Post.where(trashed: true).where(trashed: false)
779
+ Article.where(trashed: true).where(trashed: false)
813
780
  ```
814
781
 
815
782
  the SQL executed would be:
816
783
 
817
784
  ```sql
818
- SELECT * FROM posts WHERE `trashed` = 1 AND `trashed` = 0
785
+ SELECT * FROM articles WHERE `trashed` = 1 AND `trashed` = 0
819
786
  ```
820
787
 
821
788
  Null Relation
@@ -824,21 +791,21 @@ Null Relation
824
791
  The `none` method returns a chainable relation with no records. Any subsequent conditions chained to the returned relation will continue generating empty relations. This is useful in scenarios where you need a chainable response to a method or a scope that could return zero results.
825
792
 
826
793
  ```ruby
827
- Post.none # returns an empty Relation and fires no queries.
794
+ Article.none # returns an empty Relation and fires no queries.
828
795
  ```
829
796
 
830
797
  ```ruby
831
- # The visible_posts method below is expected to return a Relation.
832
- @posts = current_user.visible_posts.where(name: params[:name])
798
+ # The visible_articles method below is expected to return a Relation.
799
+ @articles = current_user.visible_articles.where(name: params[:name])
833
800
 
834
- def visible_posts
801
+ def visible_articles
835
802
  case role
836
803
  when 'Country Manager'
837
- Post.where(country: country)
804
+ Article.where(country: country)
838
805
  when 'Reviewer'
839
- Post.published
806
+ Article.published
840
807
  when 'Bad User'
841
- Post.none # => returning [] or nil breaks the caller code in this case
808
+ Article.none # => returning [] or nil breaks the caller code in this case
842
809
  end
843
810
  end
844
811
  ```
@@ -907,7 +874,7 @@ For example:
907
874
  Item.transaction do
908
875
  i = Item.lock.first
909
876
  i.name = 'Jones'
910
- i.save
877
+ i.save!
911
878
  end
912
879
  ```
913
880
 
@@ -963,23 +930,23 @@ SELECT clients.* FROM clients LEFT OUTER JOIN addresses ON addresses.client_id =
963
930
 
964
931
  WARNING: This method only works with `INNER JOIN`.
965
932
 
966
- Active Record lets you use the names of the [associations](association_basics.html) defined on the model as a shortcut for specifying `JOIN` clause for those associations when using the `joins` method.
933
+ Active Record lets you use the names of the [associations](association_basics.html) defined on the model as a shortcut for specifying `JOIN` clauses for those associations when using the `joins` method.
967
934
 
968
- For example, consider the following `Category`, `Post`, `Comment`, `Guest` and `Tag` models:
935
+ For example, consider the following `Category`, `Article`, `Comment`, `Guest` and `Tag` models:
969
936
 
970
937
  ```ruby
971
938
  class Category < ActiveRecord::Base
972
- has_many :posts
939
+ has_many :articles
973
940
  end
974
941
 
975
- class Post < ActiveRecord::Base
942
+ class Article < ActiveRecord::Base
976
943
  belongs_to :category
977
944
  has_many :comments
978
945
  has_many :tags
979
946
  end
980
947
 
981
948
  class Comment < ActiveRecord::Base
982
- belongs_to :post
949
+ belongs_to :article
983
950
  has_one :guest
984
951
  end
985
952
 
@@ -988,7 +955,7 @@ class Guest < ActiveRecord::Base
988
955
  end
989
956
 
990
957
  class Tag < ActiveRecord::Base
991
- belongs_to :post
958
+ belongs_to :article
992
959
  end
993
960
  ```
994
961
 
@@ -997,64 +964,64 @@ Now all of the following will produce the expected join queries using `INNER JOI
997
964
  #### Joining a Single Association
998
965
 
999
966
  ```ruby
1000
- Category.joins(:posts)
967
+ Category.joins(:articles)
1001
968
  ```
1002
969
 
1003
970
  This produces:
1004
971
 
1005
972
  ```sql
1006
973
  SELECT categories.* FROM categories
1007
- INNER JOIN posts ON posts.category_id = categories.id
974
+ INNER JOIN articles ON articles.category_id = categories.id
1008
975
  ```
1009
976
 
1010
- Or, in English: "return a Category object for all categories with posts". Note that you will see duplicate categories if more than one post has the same category. If you want unique categories, you can use `Category.joins(:posts).uniq`.
977
+ Or, in English: "return a Category object for all categories with articles". Note that you will see duplicate categories if more than one article has the same category. If you want unique categories, you can use `Category.joins(:articles).uniq`.
1011
978
 
1012
979
  #### Joining Multiple Associations
1013
980
 
1014
981
  ```ruby
1015
- Post.joins(:category, :comments)
982
+ Article.joins(:category, :comments)
1016
983
  ```
1017
984
 
1018
985
  This produces:
1019
986
 
1020
987
  ```sql
1021
- SELECT posts.* FROM posts
1022
- INNER JOIN categories ON posts.category_id = categories.id
1023
- INNER JOIN comments ON comments.post_id = posts.id
988
+ SELECT articles.* FROM articles
989
+ INNER JOIN categories ON articles.category_id = categories.id
990
+ INNER JOIN comments ON comments.article_id = articles.id
1024
991
  ```
1025
992
 
1026
- Or, in English: "return all posts that have a category and at least one comment". Note again that posts with multiple comments will show up multiple times.
993
+ Or, in English: "return all articles that have a category and at least one comment". Note again that articles with multiple comments will show up multiple times.
1027
994
 
1028
995
  #### Joining Nested Associations (Single Level)
1029
996
 
1030
997
  ```ruby
1031
- Post.joins(comments: :guest)
998
+ Article.joins(comments: :guest)
1032
999
  ```
1033
1000
 
1034
1001
  This produces:
1035
1002
 
1036
1003
  ```sql
1037
- SELECT posts.* FROM posts
1038
- INNER JOIN comments ON comments.post_id = posts.id
1004
+ SELECT articles.* FROM articles
1005
+ INNER JOIN comments ON comments.article_id = articles.id
1039
1006
  INNER JOIN guests ON guests.comment_id = comments.id
1040
1007
  ```
1041
1008
 
1042
- Or, in English: "return all posts that have a comment made by a guest."
1009
+ Or, in English: "return all articles that have a comment made by a guest."
1043
1010
 
1044
1011
  #### Joining Nested Associations (Multiple Level)
1045
1012
 
1046
1013
  ```ruby
1047
- Category.joins(posts: [{ comments: :guest }, :tags])
1014
+ Category.joins(articles: [{ comments: :guest }, :tags])
1048
1015
  ```
1049
1016
 
1050
1017
  This produces:
1051
1018
 
1052
1019
  ```sql
1053
1020
  SELECT categories.* FROM categories
1054
- INNER JOIN posts ON posts.category_id = categories.id
1055
- INNER JOIN comments ON comments.post_id = posts.id
1021
+ INNER JOIN articles ON articles.category_id = categories.id
1022
+ INNER JOIN comments ON comments.article_id = articles.id
1056
1023
  INNER JOIN guests ON guests.comment_id = comments.id
1057
- INNER JOIN tags ON tags.post_id = posts.id
1024
+ INNER JOIN tags ON tags.article_id = articles.id
1058
1025
  ```
1059
1026
 
1060
1027
  ### Specifying Conditions on the Joined Tables
@@ -1123,18 +1090,18 @@ Active Record lets you eager load any number of associations with a single `Mode
1123
1090
  #### Array of Multiple Associations
1124
1091
 
1125
1092
  ```ruby
1126
- Post.includes(:category, :comments)
1093
+ Article.includes(:category, :comments)
1127
1094
  ```
1128
1095
 
1129
- This loads all the posts and the associated category and comments for each post.
1096
+ This loads all the articles and the associated category and comments for each article.
1130
1097
 
1131
1098
  #### Nested Associations Hash
1132
1099
 
1133
1100
  ```ruby
1134
- Category.includes(posts: [{ comments: :guest }, :tags]).find(1)
1101
+ Category.includes(articles: [{ comments: :guest }, :tags]).find(1)
1135
1102
  ```
1136
1103
 
1137
- This will find the category with id 1 and eager load all of the associated posts, the associated posts' tags and comments, and every comment's guest association.
1104
+ This will find the category with id 1 and eager load all of the associated articles, the associated articles' tags and comments, and every comment's guest association.
1138
1105
 
1139
1106
  ### Specifying Conditions on Eager Loaded Associations
1140
1107
 
@@ -1143,18 +1110,31 @@ Even though Active Record lets you specify conditions on the eager loaded associ
1143
1110
  However if you must do this, you may use `where` as you would normally.
1144
1111
 
1145
1112
  ```ruby
1146
- Post.includes(:comments).where("comments.visible" => true)
1113
+ Article.includes(:comments).where(comments: { visible: true })
1147
1114
  ```
1148
1115
 
1149
- This would generate a query which contains a `LEFT OUTER JOIN` whereas the `joins` method would generate one using the `INNER JOIN` function instead.
1116
+ This would generate a query which contains a `LEFT OUTER JOIN` whereas the
1117
+ `joins` method would generate one using the `INNER JOIN` function instead.
1150
1118
 
1151
1119
  ```ruby
1152
- SELECT "posts"."id" AS t0_r0, ... "comments"."updated_at" AS t1_r5 FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE (comments.visible = 1)
1120
+ SELECT "articles"."id" AS t0_r0, ... "comments"."updated_at" AS t1_r5 FROM "articles" LEFT OUTER JOIN "comments" ON "comments"."article_id" = "articles"."id" WHERE (comments.visible = 1)
1153
1121
  ```
1154
1122
 
1155
1123
  If there was no `where` condition, this would generate the normal set of two queries.
1156
1124
 
1157
- If, in the case of this `includes` query, there were no comments for any posts, all the posts would still be loaded. By using `joins` (an INNER JOIN), the join conditions **must** match, otherwise no records will be returned.
1125
+ NOTE: Using `where` like this will only work when you pass it a Hash. For
1126
+ SQL-fragments you need use `references` to force joined tables:
1127
+
1128
+ ```ruby
1129
+ Article.includes(:comments).where("comments.visible = true").references(:comments)
1130
+ ```
1131
+
1132
+ If, in the case of this `includes` query, there were no comments for any
1133
+ articles, all the articles would still be loaded. By using `joins` (an INNER
1134
+ JOIN), the join conditions **must** match, otherwise no records will be
1135
+ returned.
1136
+
1137
+
1158
1138
 
1159
1139
  Scopes
1160
1140
  ------
@@ -1164,7 +1144,7 @@ Scoping allows you to specify commonly-used queries which can be referenced as m
1164
1144
  To define a simple scope, we use the `scope` method inside the class, passing the query that we'd like to run when this scope is called:
1165
1145
 
1166
1146
  ```ruby
1167
- class Post < ActiveRecord::Base
1147
+ class Article < ActiveRecord::Base
1168
1148
  scope :published, -> { where(published: true) }
1169
1149
  end
1170
1150
  ```
@@ -1172,7 +1152,7 @@ end
1172
1152
  This is exactly the same as defining a class method, and which you use is a matter of personal preference:
1173
1153
 
1174
1154
  ```ruby
1175
- class Post < ActiveRecord::Base
1155
+ class Article < ActiveRecord::Base
1176
1156
  def self.published
1177
1157
  where(published: true)
1178
1158
  end
@@ -1182,7 +1162,7 @@ end
1182
1162
  Scopes are also chainable within scopes:
1183
1163
 
1184
1164
  ```ruby
1185
- class Post < ActiveRecord::Base
1165
+ class Article < ActiveRecord::Base
1186
1166
  scope :published, -> { where(published: true) }
1187
1167
  scope :published_and_commented, -> { published.where("comments_count > 0") }
1188
1168
  end
@@ -1191,14 +1171,14 @@ end
1191
1171
  To call this `published` scope we can call it on either the class:
1192
1172
 
1193
1173
  ```ruby
1194
- Post.published # => [published posts]
1174
+ Article.published # => [published articles]
1195
1175
  ```
1196
1176
 
1197
- Or on an association consisting of `Post` objects:
1177
+ Or on an association consisting of `Article` objects:
1198
1178
 
1199
1179
  ```ruby
1200
1180
  category = Category.first
1201
- category.posts.published # => [published posts belonging to this category]
1181
+ category.articles.published # => [published articles belonging to this category]
1202
1182
  ```
1203
1183
 
1204
1184
  ### Passing in arguments
@@ -1206,7 +1186,7 @@ category.posts.published # => [published posts belonging to this category]
1206
1186
  Your scope can take arguments:
1207
1187
 
1208
1188
  ```ruby
1209
- class Post < ActiveRecord::Base
1189
+ class Article < ActiveRecord::Base
1210
1190
  scope :created_before, ->(time) { where("created_at < ?", time) }
1211
1191
  end
1212
1192
  ```
@@ -1214,13 +1194,13 @@ end
1214
1194
  Call the scope as if it were a class method:
1215
1195
 
1216
1196
  ```ruby
1217
- Post.created_before(Time.zone.now)
1197
+ Article.created_before(Time.zone.now)
1218
1198
  ```
1219
1199
 
1220
1200
  However, this is just duplicating the functionality that would be provided to you by a class method.
1221
1201
 
1222
1202
  ```ruby
1223
- class Post < ActiveRecord::Base
1203
+ class Article < ActiveRecord::Base
1224
1204
  def self.created_before(time)
1225
1205
  where("created_at < ?", time)
1226
1206
  end
@@ -1230,7 +1210,36 @@ end
1230
1210
  Using a class method is the preferred way to accept arguments for scopes. These methods will still be accessible on the association objects:
1231
1211
 
1232
1212
  ```ruby
1233
- category.posts.created_before(time)
1213
+ category.articles.created_before(time)
1214
+ ```
1215
+
1216
+ ### Applying a default scope
1217
+
1218
+ If we wish for a scope to be applied across all queries to the model we can use the
1219
+ `default_scope` method within the model itself.
1220
+
1221
+ ```ruby
1222
+ class Client < ActiveRecord::Base
1223
+ default_scope { where("removed_at IS NULL") }
1224
+ end
1225
+ ```
1226
+
1227
+ When queries are executed on this model, the SQL query will now look something like
1228
+ this:
1229
+
1230
+ ```sql
1231
+ SELECT * FROM clients WHERE removed_at IS NULL
1232
+ ```
1233
+
1234
+ If you need to do more complex things with a default scope, you can alternatively
1235
+ define it as a class method:
1236
+
1237
+ ```ruby
1238
+ class Client < ActiveRecord::Base
1239
+ def self.default_scope
1240
+ # Should return an ActiveRecord::Relation.
1241
+ end
1242
+ end
1234
1243
  ```
1235
1244
 
1236
1245
  ### Merging of scopes
@@ -1286,36 +1295,6 @@ User.where(state: 'inactive')
1286
1295
  As you can see above the `default_scope` is being merged in both
1287
1296
  `scope` and `where` conditions.
1288
1297
 
1289
-
1290
- ### Applying a default scope
1291
-
1292
- If we wish for a scope to be applied across all queries to the model we can use the
1293
- `default_scope` method within the model itself.
1294
-
1295
- ```ruby
1296
- class Client < ActiveRecord::Base
1297
- default_scope { where("removed_at IS NULL") }
1298
- end
1299
- ```
1300
-
1301
- When queries are executed on this model, the SQL query will now look something like
1302
- this:
1303
-
1304
- ```sql
1305
- SELECT * FROM clients WHERE removed_at IS NULL
1306
- ```
1307
-
1308
- If you need to do more complex things with a default scope, you can alternatively
1309
- define it as a class method:
1310
-
1311
- ```ruby
1312
- class Client < ActiveRecord::Base
1313
- def self.default_scope
1314
- # Should return an ActiveRecord::Relation.
1315
- end
1316
- end
1317
- ```
1318
-
1319
1298
  ### Removing All Scoping
1320
1299
 
1321
1300
  If we wish to remove scoping for any reason we can use the `unscoped` method. This is
@@ -1458,6 +1437,11 @@ If you'd like to use your own SQL to find records in a table you can use `find_b
1458
1437
  Client.find_by_sql("SELECT * FROM clients
1459
1438
  INNER JOIN orders ON clients.id = orders.client_id
1460
1439
  ORDER BY clients.created_at desc")
1440
+ # => [
1441
+ #<Client id: 1, first_name: "Lucas" >,
1442
+ #<Client id: 2, first_name: "Jan" >,
1443
+ # ...
1444
+ ]
1461
1445
  ```
1462
1446
 
1463
1447
  `find_by_sql` provides you with a simple way of making custom calls to the database and retrieving instantiated objects.
@@ -1467,12 +1451,16 @@ Client.find_by_sql("SELECT * FROM clients
1467
1451
  `find_by_sql` has a close relative called `connection#select_all`. `select_all` will retrieve objects from the database using custom SQL just like `find_by_sql` but will not instantiate them. Instead, you will get an array of hashes where each hash indicates a record.
1468
1452
 
1469
1453
  ```ruby
1470
- Client.connection.select_all("SELECT * FROM clients WHERE id = '1'")
1454
+ Client.connection.select_all("SELECT first_name, created_at FROM clients WHERE id = '1'")
1455
+ # => [
1456
+ {"first_name"=>"Rafael", "created_at"=>"2012-11-10 23:23:45.281189"},
1457
+ {"first_name"=>"Eileen", "created_at"=>"2013-12-09 11:22:35.221282"}
1458
+ ]
1471
1459
  ```
1472
1460
 
1473
1461
  ### `pluck`
1474
1462
 
1475
- `pluck` can be used to query a single or multiple columns from the underlying table of a model. It accepts a list of column names as argument and returns an array of values of the specified columns with the corresponding data type.
1463
+ `pluck` can be used to query single or multiple columns from the underlying table of a model. It accepts a list of column names as argument and returns an array of values of the specified columns with the corresponding data type.
1476
1464
 
1477
1465
  ```ruby
1478
1466
  Client.where(active: true).pluck(:id)
@@ -1594,20 +1582,20 @@ You can also use `any?` and `many?` to check for existence on a model or relatio
1594
1582
 
1595
1583
  ```ruby
1596
1584
  # via a model
1597
- Post.any?
1598
- Post.many?
1585
+ Article.any?
1586
+ Article.many?
1599
1587
 
1600
1588
  # via a named scope
1601
- Post.recent.any?
1602
- Post.recent.many?
1589
+ Article.recent.any?
1590
+ Article.recent.many?
1603
1591
 
1604
1592
  # via a relation
1605
- Post.where(published: true).any?
1606
- Post.where(published: true).many?
1593
+ Article.where(published: true).any?
1594
+ Article.where(published: true).many?
1607
1595
 
1608
1596
  # via an association
1609
- Post.first.categories.any?
1610
- Post.first.categories.many?
1597
+ Article.first.categories.any?
1598
+ Article.first.categories.many?
1611
1599
  ```
1612
1600
 
1613
1601
  Calculations
@@ -1697,19 +1685,26 @@ Running EXPLAIN
1697
1685
  You can run EXPLAIN on the queries triggered by relations. For example,
1698
1686
 
1699
1687
  ```ruby
1700
- User.where(id: 1).joins(:posts).explain
1688
+ User.where(id: 1).joins(:articles).explain
1701
1689
  ```
1702
1690
 
1703
1691
  may yield
1704
1692
 
1705
1693
  ```
1706
- EXPLAIN for: SELECT `users`.* FROM `users` INNER JOIN `posts` ON `posts`.`user_id` = `users`.`id` WHERE `users`.`id` = 1
1707
- +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
1708
- | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
1709
- +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
1710
- | 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | |
1711
- | 1 | SIMPLE | posts | ALL | NULL | NULL | NULL | NULL | 1 | Using where |
1712
- +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
1694
+ EXPLAIN for: SELECT `users`.* FROM `users` INNER JOIN `articles` ON `articles`.`user_id` = `users`.`id` WHERE `users`.`id` = 1
1695
+ +----+-------------+----------+-------+---------------+
1696
+ | id | select_type | table | type | possible_keys |
1697
+ +----+-------------+----------+-------+---------------+
1698
+ | 1 | SIMPLE | users | const | PRIMARY |
1699
+ | 1 | SIMPLE | articles | ALL | NULL |
1700
+ +----+-------------+----------+-------+---------------+
1701
+ +---------+---------+-------+------+-------------+
1702
+ | key | key_len | ref | rows | Extra |
1703
+ +---------+---------+-------+------+-------------+
1704
+ | PRIMARY | 4 | const | 1 | |
1705
+ | NULL | NULL | NULL | 1 | Using where |
1706
+ +---------+---------+-------+------+-------------+
1707
+
1713
1708
  2 rows in set (0.00 sec)
1714
1709
  ```
1715
1710
 
@@ -1719,15 +1714,15 @@ Active Record performs a pretty printing that emulates the one of the database
1719
1714
  shells. So, the same query running with the PostgreSQL adapter would yield instead
1720
1715
 
1721
1716
  ```
1722
- EXPLAIN for: SELECT "users".* FROM "users" INNER JOIN "posts" ON "posts"."user_id" = "users"."id" WHERE "users"."id" = 1
1717
+ EXPLAIN for: SELECT "users".* FROM "users" INNER JOIN "articles" ON "articles"."user_id" = "users"."id" WHERE "users"."id" = 1
1723
1718
  QUERY PLAN
1724
1719
  ------------------------------------------------------------------------------
1725
1720
  Nested Loop Left Join (cost=0.00..37.24 rows=8 width=0)
1726
- Join Filter: (posts.user_id = users.id)
1721
+ Join Filter: (articles.user_id = users.id)
1727
1722
  -> Index Scan using users_pkey on users (cost=0.00..8.27 rows=1 width=4)
1728
1723
  Index Cond: (id = 1)
1729
- -> Seq Scan on posts (cost=0.00..28.88 rows=8 width=4)
1730
- Filter: (posts.user_id = 1)
1724
+ -> Seq Scan on articles (cost=0.00..28.88 rows=8 width=4)
1725
+ Filter: (articles.user_id = 1)
1731
1726
  (6 rows)
1732
1727
  ```
1733
1728
 
@@ -1736,26 +1731,39 @@ may need the results of previous ones. Because of that, `explain` actually
1736
1731
  executes the query, and then asks for the query plans. For example,
1737
1732
 
1738
1733
  ```ruby
1739
- User.where(id: 1).includes(:posts).explain
1734
+ User.where(id: 1).includes(:articles).explain
1740
1735
  ```
1741
1736
 
1742
1737
  yields
1743
1738
 
1744
1739
  ```
1745
1740
  EXPLAIN for: SELECT `users`.* FROM `users` WHERE `users`.`id` = 1
1746
- +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
1747
- | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
1748
- +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
1749
- | 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | |
1750
- +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
1741
+ +----+-------------+-------+-------+---------------+
1742
+ | id | select_type | table | type | possible_keys |
1743
+ +----+-------------+-------+-------+---------------+
1744
+ | 1 | SIMPLE | users | const | PRIMARY |
1745
+ +----+-------------+-------+-------+---------------+
1746
+ +---------+---------+-------+------+-------+
1747
+ | key | key_len | ref | rows | Extra |
1748
+ +---------+---------+-------+------+-------+
1749
+ | PRIMARY | 4 | const | 1 | |
1750
+ +---------+---------+-------+------+-------+
1751
+
1751
1752
  1 row in set (0.00 sec)
1752
1753
 
1753
- EXPLAIN for: SELECT `posts`.* FROM `posts` WHERE `posts`.`user_id` IN (1)
1754
- +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1755
- | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
1756
- +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1757
- | 1 | SIMPLE | posts | ALL | NULL | NULL | NULL | NULL | 1 | Using where |
1758
- +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1754
+ EXPLAIN for: SELECT `articles`.* FROM `articles` WHERE `articles`.`user_id` IN (1)
1755
+ +----+-------------+----------+------+---------------+
1756
+ | id | select_type | table | type | possible_keys |
1757
+ +----+-------------+----------+------+---------------+
1758
+ | 1 | SIMPLE | articles | ALL | NULL |
1759
+ +----+-------------+----------+------+---------------+
1760
+ +------+---------+------+------+-------------+
1761
+ | key | key_len | ref | rows | Extra |
1762
+ +------+---------+------+------+-------------+
1763
+ | NULL | NULL | NULL | 1 | Using where |
1764
+ +------+---------+------+------+-------------+
1765
+
1766
+
1759
1767
  1 row in set (0.00 sec)
1760
1768
  ```
1761
1769