“1b089a083f7ef854b58edb81c759ad34e70943da”上不存在“guides/source/active_record_querying.md”
active_record_querying.md 54.2 KB
Newer Older
1 2
Active Record Query Interface
=============================
3

4 5 6
This guide covers different ways to retrieve data from the database using Active Record.

After reading this guide, you will know:
7

8 9 10 11 12 13 14
* How to find records using a variety of methods and conditions.
* How to specify the order, retrieved attributes, grouping, and other properties of the found records.
* How to use eager loading to reduce the number of database queries needed for data retrieval.
* How to use dynamic finders methods.
* How to check for the existence of particular records.
* How to perform various calculations on Active Record models.
* How to run EXPLAIN on relations.
15

16
--------------------------------------------------------------------------------
17

18
If you're used to using raw SQL to find database records, then you will generally find that there are better ways to carry out the same operations in Rails. Active Record insulates you from the need to use SQL in most cases.
19 20 21

Code examples throughout this guide will refer to one or more of the following models:

22
TIP: All of the following models use `id` as the primary key, unless specified otherwise.
23

24
```ruby
25 26 27 28 29
class Client < ActiveRecord::Base
  has_one :address
  has_many :orders
  has_and_belongs_to_many :roles
end
30
```
31

32
```ruby
33 34 35
class Address < ActiveRecord::Base
  belongs_to :client
end
36
```
37

38
```ruby
39
class Order < ActiveRecord::Base
A
Agis Anastasopoulos 已提交
40
  belongs_to :client, counter_cache: true
41
end
42
```
43

44
```ruby
45 46 47
class Role < ActiveRecord::Base
  has_and_belongs_to_many :clients
end
48
```
49

50
Active Record will perform queries on the database for you and is compatible with most database systems (MySQL, PostgreSQL and SQLite to name a few). Regardless of which database system you're using, the Active Record method format will always be the same.
51

52 53
Retrieving Objects from the Database
------------------------------------
54

55
To retrieve objects from the database, Active Record provides several finder methods. Each finder method allows you to pass arguments into it to perform certain queries on your database without writing raw SQL.
56 57

The methods are:
58

59 60
* `bind`
* `create_with`
61
* `distinct`
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
* `eager_load`
* `extending`
* `from`
* `group`
* `having`
* `includes`
* `joins`
* `limit`
* `lock`
* `none`
* `offset`
* `order`
* `preload`
* `readonly`
* `references`
* `reorder`
* `reverse_order`
* `select`
* `uniq`
* `where`
82

83
All of the above methods return an instance of `ActiveRecord::Relation`.
84

85
The primary operation of `Model.find(options)` can be summarized as:
86 87 88 89

* Convert the supplied options to an equivalent SQL query.
* Fire the SQL query and retrieve the corresponding results from the database.
* Instantiate the equivalent Ruby object of the appropriate model for every resulting row.
90
* Run `after_find` callbacks, if any.
91

92
### Retrieving a Single Object
93

94
Active Record provides several different ways of retrieving a single object.
95

96
#### Using a Primary Key
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:
99

100
```ruby
101 102
# Find the client with primary key (id) 10.
client = Client.find(10)
103
# => #<Client id: 10, first_name: "Ryan">
104
```
105

106
The SQL equivalent of the above is:
107

108
```sql
109
SELECT * FROM clients WHERE (clients.id = 10) LIMIT 1
110
```
111

112
`Model.find(primary_key)` will raise an `ActiveRecord::RecordNotFound` exception if no matching record is found.
113

114
#### `take`
115

116
`Model.take` retrieves a record without any implicit ordering. For example:
117

118
```ruby
119 120
client = Client.take
# => #<Client id: 1, first_name: "Lifo">
121
```
122 123 124

The SQL equivalent of the above is:

125
```sql
126
SELECT * FROM clients LIMIT 1
127
```
128

129
`Model.take` returns `nil` if no record is found and no exception will be raised.
130 131

TIP: The retrieved record may vary depending on the database engine.
132

133
#### `first`
134

135
The `first` method finds the first record ordered by the primary key. For example:
136

137
```ruby
138
client = Client.first
139
# => #<Client id: 1, first_name: "Lifo">
140
```
141

142
The SQL equivalent of the above is:
143

144
```sql
145
SELECT * FROM clients ORDER BY clients.id ASC LIMIT 1
146
```
147

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
The `first` method returns `nil` if no matching record is found and no exception will be raised.

You can pass in a numerical argument to the `first` method to return up to that number of results. For example

```ruby
client = Client.first(3)
# => [
  #<Client id: 1, first_name: "Lifo">,
  #<Client id: 2, first_name: "Fifo">,
  #<Client id: 3, first_name: "Filo">
]
```

The SQL equivalent of the above is:

```sql
SELECT * FROM clients ORDER BY clients.id ASC LIMIT 3
```

The `first!` method behaves exactly like `first`, except that it will raise `ActiveRecord::RecordNotFound` if no matching record is found.
168

169
#### `last`
170

171
`Model.last` finds the last record ordered by the primary key. For example:
172

173
```ruby
174
client = Client.last
175
# => #<Client id: 221, first_name: "Russel">
176
```
177

178
The SQL equivalent of the above is:
179

180
```sql
181
SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1
182
```
183

184
`Model.last` returns `nil` if no matching record is found and no exception will be raised.
185

186
#### `find_by`
187

188
The `find_by` method finds the first record matching some conditions. For example:
189

190
```ruby
191 192 193 194 195
Client.find_by first_name: 'Lifo'
# => #<Client id: 1, first_name: "Lifo">

Client.find_by first_name: 'Jon'
# => nil
196
```
197 198 199

It is equivalent to writing:

200
```ruby
201
Client.where(first_name: 'Lifo').take
202
```
203

204 205 206 207 208 209 210 211 212 213 214 215 216
The `find_by!` method behaves exactly like `find_by`, except that it will raise `ActiveRecord::RecordNotFound` if no matching record is found. For example:

```ruby
Client.find_by! first_name: 'does not exist'
# => ActiveRecord::RecordNotFound
```

This is equivalent to writing:

```ruby
Client.where(first_name: 'does not exist').take!
```

217
#### `take!`
218

219
`Model.take!` retrieves a record without any implicit ordering. For example:
220

221
```ruby
222 223
client = Client.take!
# => #<Client id: 1, first_name: "Lifo">
224
```
225 226 227

The SQL equivalent of the above is:

228
```sql
229
SELECT * FROM clients LIMIT 1
230
```
231

232
`Model.take!` raises `ActiveRecord::RecordNotFound` if no matching record is found.
233

234
#### `last!`
235

236
`Model.last!` finds the last record ordered by the primary key. For example:
237

238
```ruby
239
client = Client.last!
240
# => #<Client id: 221, first_name: "Russel">
241
```
242

243
The SQL equivalent of the above is:
244

245
```sql
246
SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1
247
```
248

249
`Model.last!` raises `ActiveRecord::RecordNotFound` if no matching record is found.
250

251
### Retrieving Multiple Objects
252

253
#### Using Multiple Primary Keys
254

255
`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:
256

257
```ruby
258
# Find the clients with primary keys 1 and 10.
259
client = Client.find([1, 10]) # Or even Client.find(1, 10)
260
# => [#<Client id: 1, first_name: "Lifo">, #<Client id: 10, first_name: "Ryan">]
261
```
262

263
The SQL equivalent of the above is:
264

265
```sql
266
SELECT * FROM clients WHERE (clients.id IN (1,10))
267
```
268

269
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.
270

271
#### take
272

273
`Model.take(limit)` retrieves the first number of records specified by `limit` without any explicit ordering:
274

275
```ruby
276
Client.take(2)
V
Vijay Dev 已提交
277
# => [#<Client id: 1, first_name: "Lifo">,
278
      #<Client id: 2, first_name: "Raf">]
279
```
280 281 282

The SQL equivalent of the above is:

283
```sql
284
SELECT * FROM clients LIMIT 2
285
```
286

287
#### last
288

289
`Model.last(limit)` finds the number of records specified by `limit` ordered by primary key in descending order:
290

291
```ruby
292
Client.last(2)
V
Vijay Dev 已提交
293
# => [#<Client id: 10, first_name: "Ryan">,
294
      #<Client id: 9, first_name: "John">]
295
```
296 297 298

The SQL equivalent of the above is:

299
```sql
300
SELECT * FROM clients ORDER BY id DESC LIMIT 2
301
```
302

303
### Retrieving Multiple Objects in Batches
304

305
We often need to iterate over a large set of records, as when we send a newsletter to a large set of users, or when we export data.
306

307
This may appear straightforward:
308

309
```ruby
310
# This is very inefficient when the users table has thousands of rows.
P
Pratik Naik 已提交
311
User.all.each do |user|
312 313
  NewsLetter.weekly_deliver(user)
end
314
```
315

316
But this approach becomes increasingly impractical as the table size increases, since `User.all.each` instructs Active Record to fetch _the entire table_ in a single pass, build a model object per row, and then keep the entire array of model objects in memory. Indeed, if we have a large number of records, the entire collection may exceed the amount of memory available.
317

318
Rails provides two methods that address this problem by dividing records into memory-friendly batches for processing. The first method, `find_each`, retrieves a batch of records and then yields _each_ record to the block individually as a model. The second method, `find_in_batches`, retrieves a batch of records and then yields _the entire batch_ to the block as an array of models.
319

320
TIP: The `find_each` and `find_in_batches` methods are intended for use in the batch processing of a large number of records that wouldn't fit in memory all at once. If you just need to loop over a thousand records the regular find methods are the preferred option.
321

322
#### `find_each`
323

324
The `find_each` method retrieves a batch of records and then yields _each_ record to the block individually as a model. In the following example, `find_each` will retrieve 1000 records (the current default for both `find_each` and `find_in_batches`) and then yield each record individually to the block as a model. This process is repeated until all of the records have been processed:
325

326
```ruby
327 328 329
User.find_each do |user|
  NewsLetter.weekly_deliver(user)
end
330
```
331

332
##### Options for `find_each`
333

334
The `find_each` method accepts most of the options allowed by the regular `find` method, except for `:order` and `:limit`, which are reserved for internal use by `find_each`.
335

336
Two additional options, `:batch_size` and `:start`, are available as well.
337

338
**`:batch_size`**
339

340
The `:batch_size` option allows you to specify the number of records to be retrieved in each batch, before being passed individually to the block. For example, to retrieve records in batches of 5000:
341

342
```ruby
A
Agis Anastasopoulos 已提交
343
User.find_each(batch_size: 5000) do |user|
344 345
  NewsLetter.weekly_deliver(user)
end
346
```
347

348
**`:start`**
349

350
By default, records are fetched in ascending order of the primary key, which must be an integer. The `:start` option allows you to configure the first ID of the sequence whenever the lowest ID is not the one you need. This would be useful, for example, if you wanted to resume an interrupted batch process, provided you saved the last processed ID as a checkpoint.
351

352
For example, to send newsletters only to users with the primary key starting from 2000, and to retrieve them in batches of 5000:
353

354
```ruby
A
Agis Anastasopoulos 已提交
355
User.find_each(start: 2000, batch_size: 5000) do |user|
356 357
  NewsLetter.weekly_deliver(user)
end
358
```
359

360
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.
361

362
#### `find_in_batches`
363

364
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:
365

366
```ruby
367
# Give add_invoices an array of 1000 invoices at a time
A
Agis Anastasopoulos 已提交
368
Invoice.find_in_batches(include: :invoice_lines) do |invoices|
369 370
  export.add_invoices(invoices)
end
371
```
372

373
NOTE: The `:include` option allows you to name associations that should be loaded alongside with the models.
374

375
##### Options for `find_in_batches`
376

377
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`.
378

379 380
Conditions
----------
381

382
The `where` method allows you to specify conditions to limit the records returned, representing the `WHERE`-part of the SQL statement. Conditions can either be specified as a string, array, or hash.
383

384
### Pure String Conditions
385

386
If you'd like to add conditions to your find, you could just specify them in there, just like `Client.where("orders_count = '2'")`. This will find all clients where the `orders_count` field's value is 2.
387

388
WARNING: Building your own conditions as pure strings can leave you vulnerable to SQL injection exploits. For example, `Client.where("first_name LIKE '%#{params[:first_name]}%'")` is not safe. See the next section for the preferred way to handle conditions using an array.
389

390
### Array Conditions
391

392
Now what if that number could vary, say as an argument from somewhere? The find would then take the form:
P
Pratik Naik 已提交
393

394
```ruby
P
Pratik Naik 已提交
395
Client.where("orders_count = ?", params[:orders])
396
```
P
Pratik Naik 已提交
397

398
Active Record will go through the first element in the conditions value and any additional elements will replace the question marks `(?)` in the first element.
P
Pratik Naik 已提交
399

400
If you want to specify multiple conditions:
P
Pratik Naik 已提交
401

402
```ruby
P
Pratik Naik 已提交
403
Client.where("orders_count = ? AND locked = ?", params[:orders], false)
404
```
P
Pratik Naik 已提交
405

406
In this example, the first question mark will be replaced with the value in `params[:orders]` and the second will be replaced with the SQL representation of `false`, which depends on the adapter.
407

408
This code is highly preferable:
409

410
```ruby
P
Pratik Naik 已提交
411
Client.where("orders_count = ?", params[:orders])
412
```
413

414
to this code:
415

416
```ruby
417
Client.where("orders_count = #{params[:orders]}")
418
```
419

420
because of argument safety. Putting the variable directly into the conditions string will pass the variable to the database **as-is**. This means that it will be an unescaped variable directly from a user who may have malicious intent. If you do this, you put your entire database at risk because once a user finds out they can exploit your database they can do just about anything to it. Never ever put your arguments directly inside the conditions string.
421

422
TIP: For more information on the dangers of SQL injection, see the [Ruby on Rails Security Guide](security.html#sql-injection).
423

424
#### Placeholder Conditions
P
Pratik Naik 已提交
425

426
Similar to the `(?)` replacement style of params, you can also specify keys/values hash in your array conditions:
P
Pratik Naik 已提交
427

428
```ruby
429
Client.where("created_at >= :start_date AND created_at <= :end_date",
A
Agis Anastasopoulos 已提交
430
  {start_date: params[:start_date], end_date: params[:end_date]})
431
```
P
Pratik Naik 已提交
432 433 434

This makes for clearer readability if you have a large number of variable conditions.

435
### Hash Conditions
436

437
Active Record also allows you to pass in hash conditions which can increase the readability of your conditions syntax. With hash conditions, you pass in a hash with keys of the fields you want conditionalised and the values of how you want to conditionalise them:
438

P
Pratik Naik 已提交
439 440
NOTE: Only equality, range and subset checking are possible with Hash conditions.

441
#### Equality Conditions
P
Pratik Naik 已提交
442

443
```ruby
A
Agis Anastasopoulos 已提交
444
Client.where(locked: true)
445
```
446

447
The field name can also be a string:
448

449
```ruby
450
Client.where('locked' => true)
451
```
452

S
Steve Klabnik 已提交
453
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.
454

455
```ruby
456 457
Article.where(author: author)
Author.joins(:articles).where(articles: { author: author })
458
```
459

A
Agis Anastasopoulos 已提交
460
NOTE: The values cannot be symbols. For example, you cannot do `Client.where(status: :active)`.
461

462
#### Range Conditions
P
Pratik Naik 已提交
463

464
```ruby
A
Agis Anastasopoulos 已提交
465
Client.where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight)
466
```
467

468
This will find all clients created yesterday by using a `BETWEEN` SQL statement:
469

470
```sql
471
SELECT * FROM clients WHERE (clients.created_at BETWEEN '2008-12-21 00:00:00' AND '2008-12-22 00:00:00')
472
```
473

474
This demonstrates a shorter syntax for the examples in [Array Conditions](#array-conditions)
475

476
#### Subset Conditions
P
Pratik Naik 已提交
477

478
If you want to find records using the `IN` expression you can pass an array to the conditions hash:
479

480
```ruby
A
Agis Anastasopoulos 已提交
481
Client.where(orders_count: [1,3,5])
482
```
483

P
Pratik Naik 已提交
484
This code will generate SQL like this:
485

486
```sql
487
SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5))
488
```
489

490
### NOT Conditions
491

492
`NOT` SQL queries can be built by `where.not`.
493 494

```ruby
495
Article.where.not(author: author)
496 497
```

498
In other words, this query can be generated by calling `where` with no argument, then immediately chain with `not` passing `where` conditions.
499

500 501
Ordering
--------
502

503
To retrieve records from the database in a specific order, you can use the `order` method.
504

505
For example, if you're getting a set of records and want to order them in ascending order by the `created_at` field in your table:
506

507
```ruby
508 509
Client.order(:created_at)
# OR
510
Client.order("created_at")
511
```
512

513
You could specify `ASC` or `DESC` as well:
514

515
```ruby
516 517 518 519
Client.order(created_at: :desc)
# OR
Client.order(created_at: :asc)
# OR
520
Client.order("created_at DESC")
521
# OR
522
Client.order("created_at ASC")
523
```
524 525 526

Or ordering by multiple fields:

527
```ruby
528 529 530 531
Client.order(orders_count: :asc, created_at: :desc)
# OR
Client.order(:orders_count, created_at: :desc)
# OR
532
Client.order("orders_count ASC, created_at DESC")
533 534
# OR
Client.order("orders_count ASC", "created_at DESC")
535
```
536

537
If you want to call `order` multiple times e.g. in different context, new order will append previous one
538

539
```ruby
540
Client.order("orders_count ASC").order("created_at DESC")
541
# SELECT * FROM clients ORDER BY orders_count ASC, created_at DESC
542
```
543

544 545
Selecting Specific Fields
-------------------------
546

547
By default, `Model.find` selects all the fields from the result set using `select *`.
548

549
To select only a subset of fields from the result set, you can specify the subset via the `select` method.
550

551
For example, to select only `viewable_by` and `locked` columns:
552

553
```ruby
554
Client.select("viewable_by, locked")
555
```
556 557 558

The SQL query used by this find call will be somewhat like:

559
```sql
560
SELECT viewable_by, locked FROM clients
561
```
562 563 564

Be careful because this also means you're initializing a model object with only the fields that you've selected. If you attempt to access a field that is not in the initialized record you'll receive:

P
Prem Sichanugrist 已提交
565
```bash
566
ActiveModel::MissingAttributeError: missing attribute: <attribute>
567
```
568

569
Where `<attribute>` is the attribute you asked for. The `id` method will not raise the `ActiveRecord::MissingAttributeError`, so just be careful when working with associations because they need the `id` method to function properly.
570

571
If you would like to only grab a single record per unique value in a certain field, you can use `distinct`:
572

573
```ruby
574
Client.select(:name).distinct
575
```
576 577 578

This would generate SQL like:

579
```sql
580
SELECT DISTINCT name FROM clients
581
```
582 583 584

You can also remove the uniqueness constraint:

585
```ruby
586
query = Client.select(:name).distinct
587 588
# => Returns unique names

589
query.distinct(false)
590
# => Returns all names, even if there are duplicates
591
```
592

593 594
Limit and Offset
----------------
595

596
To apply `LIMIT` to the SQL fired by the `Model.find`, you can specify the `LIMIT` using `limit` and `offset` methods on the relation.
597

598
You can use `limit` to specify the number of records to be retrieved, and use `offset` to specify the number of records to skip before starting to return the records. For example
599

600
```ruby
601
Client.limit(5)
602
```
603

604
will return a maximum of 5 clients and because it specifies no offset it will return the first 5 in the table. The SQL it executes looks like this:
605

606
```sql
607
SELECT * FROM clients LIMIT 5
608
```
609

610
Adding `offset` to that
611

612
```ruby
613
Client.limit(5).offset(30)
614
```
615

616
will return instead a maximum of 5 clients beginning with the 31st. The SQL looks like:
617

618
```sql
A
Akira Matsuda 已提交
619
SELECT * FROM clients LIMIT 5 OFFSET 30
620
```
621

622 623
Group
-----
624

625
To apply a `GROUP BY` clause to the SQL fired by the finder, you can specify the `group` method on the find.
626 627

For example, if you want to find a collection of the dates orders were created on:
628

629
```ruby
A
Akira Matsuda 已提交
630
Order.select("date(created_at) as ordered_date, sum(price) as total_price").group("date(created_at)")
631
```
632

633
And this will give you a single `Order` object for each date where there are orders in the database.
634 635 636

The SQL that would be executed would be something like this:

637
```sql
638 639
SELECT date(created_at) as ordered_date, sum(price) as total_price
FROM orders
B
Bertrand Chardon 已提交
640
GROUP BY date(created_at)
641
```
642

643 644 645 646 647 648
### Total of grouped items

To get the total of grouped items on a single query call `count` after the `group`.

```ruby
Order.group(:status).count
649
# => { 'awaiting_approval' => 7, 'paid' => 12 }
650 651 652 653 654 655 656 657 658 659
```

The SQL that would be executed would be something like this:

```sql
SELECT COUNT (*) AS count_all, status AS status
FROM "orders"
GROUP BY status
```

660 661
Having
------
662

663
SQL uses the `HAVING` clause to specify conditions on the `GROUP BY` fields. You can add the `HAVING` clause to the SQL fired by the `Model.find` by adding the `:having` option to the find.
664

665
For example:
666

667
```ruby
668 669
Order.select("date(created_at) as ordered_date, sum(price) as total_price").
  group("date(created_at)").having("sum(price) > ?", 100)
670
```
671

672 673
The SQL that would be executed would be something like this:

674
```sql
675 676 677
SELECT date(created_at) as ordered_date, sum(price) as total_price
FROM orders
GROUP BY date(created_at)
B
Bertrand Chardon 已提交
678
HAVING sum(price) > 100
679
```
680

A
Akira Matsuda 已提交
681
This will return single order objects for each day, but only those that are ordered more than $100 in a day.
682

683 684
Overriding Conditions
---------------------
685

J
Jon Leighton 已提交
686
### `unscope`
687

J
Jon Leighton 已提交
688
You can specify certain conditions to be removed using the `unscope` method. For example:
689

690
```ruby
691
Article.where('id > 10').limit(20).order('id asc').except(:order)
692
```
693 694 695

The SQL that would be executed:

696
```sql
697
SELECT * FROM articles WHERE id > 10 LIMIT 20
698

J
Jon Leighton 已提交
699
# Original query without `unscope`
700
SELECT * FROM articles WHERE id > 10 ORDER BY id asc LIMIT 20
701

702
```
703

J
Jon Leighton 已提交
704
You can additionally unscope specific where clauses. For example:
705 706

```ruby
707 708
Article.where(id: 10, trashed: false).unscope(where: :id)
# SELECT "articles".* FROM "articles" WHERE trashed = 0
709 710
```

J
Jon Leighton 已提交
711 712
A relation which has used `unscope` will affect any relation it is
merged in to:
713 714

```ruby
715 716
Article.order('id asc').merge(Article.unscope(:order))
# SELECT "articles".* FROM "articles"
717 718
```

719
### `only`
720

721
You can also override conditions using the `only` method. For example:
722

723
```ruby
724
Article.where('id > 10').limit(20).order('id desc').only(:order, :where)
725
```
726 727 728

The SQL that would be executed:

729
```sql
730
SELECT * FROM articles WHERE id > 10 ORDER BY id DESC
731 732

# Original query without `only`
733
SELECT "articles".* FROM "articles" WHERE (id > 10) ORDER BY id desc LIMIT 20
734

735
```
736

737
### `reorder`
738

739
The `reorder` method overrides the default scope order. For example:
740

741
```ruby
742
class Article < ActiveRecord::Base
743 744
  ..
  ..
745
  has_many :comments, -> { order('posted_at DESC') }
746 747
end

748
Article.find(10).comments.reorder('name')
749
```
750 751 752

The SQL that would be executed:

753
```sql
754 755
SELECT * FROM articles WHERE id = 10
SELECT * FROM comments WHERE article_id = 10 ORDER BY name
756
```
757

758
In case the `reorder` clause is not used, the SQL executed would be:
759

760
```sql
761 762
SELECT * FROM articles WHERE id = 10
SELECT * FROM comments WHERE article_id = 10 ORDER BY posted_at DESC
763
```
764

765
### `reverse_order`
766

767
The `reverse_order` method reverses the ordering clause if specified.
768

769
```ruby
770
Client.where("orders_count > 10").order(:name).reverse_order
771
```
772 773

The SQL that would be executed:
774

775
```sql
776
SELECT * FROM clients WHERE orders_count > 10 ORDER BY name DESC
777
```
778

779
If no ordering clause is specified in the query, the `reverse_order` orders by the primary key in reverse order.
780

781
```ruby
782
Client.where("orders_count > 10").reverse_order
783
```
784 785

The SQL that would be executed:
786

787
```sql
788
SELECT * FROM clients WHERE orders_count > 10 ORDER BY clients.id DESC
789
```
790

791
This method accepts **no** arguments.
792

793 794 795 796 797
### `rewhere`

The `rewhere` method overrides an existing, named where condition. For example:

```ruby
798
Article.where(trashed: true).rewhere(trashed: false)
799 800 801 802 803
```

The SQL that would be executed:

```sql
804
SELECT * FROM articles WHERE `trashed` = 0
805 806 807 808 809
```

In case the `rewhere` clause is not used,

```ruby
810
Article.where(trashed: true).where(trashed: false)
811 812 813 814 815
```

the SQL executed would be:

```sql
816
SELECT * FROM articles WHERE `trashed` = 1 AND `trashed` = 0
817 818
```

819 820
Null Relation
-------------
821

822
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.
823

824
```ruby
825
Article.none # returns an empty Relation and fires no queries.
826
```
827

828
```ruby
829 830
# The visible_articles method below is expected to return a Relation.
@articles = current_user.visible_articles.where(name: params[:name])
831

832
def visible_articles
833 834
  case role
  when 'Country Manager'
835
    Article.where(country: country)
836
  when 'Reviewer'
837
    Article.published
838
  when 'Bad User'
839
    Article.none # => returning [] or nil breaks the caller code in this case
840 841
  end
end
842
```
843

844 845
Readonly Objects
----------------
846

847
Active Record provides `readonly` method on a relation to explicitly disallow modification of any of the returned objects. Any attempt to alter a readonly record will not succeed, raising an `ActiveRecord::ReadOnlyRecord` exception.
848

849
```ruby
P
Pratik Naik 已提交
850 851
client = Client.readonly.first
client.visits += 1
852
client.save
853
```
854

855
As `client` is explicitly set to be a readonly object, the above code will raise an `ActiveRecord::ReadOnlyRecord` exception when calling `client.save` with an updated value of _visits_.
P
Pratik Naik 已提交
856

857 858
Locking Records for Update
--------------------------
859

860 861 862
Locking is helpful for preventing race conditions when updating records in the database and ensuring atomic updates.

Active Record provides two locking mechanisms:
863 864 865 866

* Optimistic Locking
* Pessimistic Locking

867
### Optimistic Locking
868

869
Optimistic locking allows multiple users to access the same record for edits, and assumes a minimum of conflicts with the data. It does this by checking whether another process has made changes to a record since it was opened. An `ActiveRecord::StaleObjectError` exception is thrown if that has occurred and the update is ignored.
870

871
**Optimistic locking column**
872

873
In order to use optimistic locking, the table needs to have a column called `lock_version` of type integer. Each time the record is updated, Active Record increments the `lock_version` column. If an update request is made with a lower value in the `lock_version` field than is currently in the `lock_version` column in the database, the update request will fail with an `ActiveRecord::StaleObjectError`. Example:
874

875
```ruby
876 877 878
c1 = Client.find(1)
c2 = Client.find(1)

879
c1.first_name = "Michael"
880 881 882
c1.save

c2.name = "should fail"
M
Michael Hutchinson 已提交
883
c2.save # Raises an ActiveRecord::StaleObjectError
884
```
885 886 887

You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging, or otherwise apply the business logic needed to resolve the conflict.

888
This behavior can be turned off by setting `ActiveRecord::Base.lock_optimistically = false`.
889

890
To override the name of the `lock_version` column, `ActiveRecord::Base` provides a class attribute called `locking_column`:
891

892
```ruby
893
class Client < ActiveRecord::Base
894
  self.locking_column = :lock_client_column
895
end
896
```
897

898
### Pessimistic Locking
899

900
Pessimistic locking uses a locking mechanism provided by the underlying database. Using `lock` when building a relation obtains an exclusive lock on the selected rows. Relations using `lock` are usually wrapped inside a transaction for preventing deadlock conditions.
901 902

For example:
903

904
```ruby
905
Item.transaction do
P
Pratik Naik 已提交
906
  i = Item.lock.first
907 908
  i.name = 'Jones'
  i.save
909
end
910
```
911

912 913
The above session produces the following SQL for a MySQL backend:

914
```sql
915 916 917 918
SQL (0.2ms)   BEGIN
Item Load (0.3ms)   SELECT * FROM `items` LIMIT 1 FOR UPDATE
Item Update (0.4ms)   UPDATE `items` SET `updated_at` = '2009-02-07 18:05:56', `name` = 'Jones' WHERE `id` = 1
SQL (0.8ms)   COMMIT
919
```
920

921
You can also pass raw SQL to the `lock` method for allowing different types of locks. For example, MySQL has an expression called `LOCK IN SHARE MODE` where you can lock a record but still allow other queries to read it. To specify this expression just pass it in as the lock option:
922

923
```ruby
924
Item.transaction do
P
Pratik Naik 已提交
925
  i = Item.lock("LOCK IN SHARE MODE").find(1)
926 927
  i.increment!(:views)
end
928
```
929

930 931
If you already have an instance of your model, you can start a transaction and acquire the lock in one go using the following code:

932
```ruby
933 934 935 936 937 938
item = Item.first
item.with_lock do
  # This block is called within a transaction,
  # item is already locked.
  item.increment!(:views)
end
939
```
940

941 942
Joining Tables
--------------
943

944
Active Record provides a finder method called `joins` for specifying `JOIN` clauses on the resulting SQL. There are multiple ways to use the `joins` method.
945

946
### Using a String SQL Fragment
947

948
You can just supply the raw SQL specifying the `JOIN` clause to `joins`:
949

950
```ruby
P
Pratik Naik 已提交
951
Client.joins('LEFT OUTER JOIN addresses ON addresses.client_id = clients.id')
952
```
953 954 955

This will result in the following SQL:

956
```sql
P
Pratik Naik 已提交
957
SELECT clients.* FROM clients LEFT OUTER JOIN addresses ON addresses.client_id = clients.id
958
```
959

960
### Using Array/Hash of Named Associations
961

962
WARNING: This method only works with `INNER JOIN`.
963

964
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.
965

966
For example, consider the following `Category`, `Article`, `Comment`, `Guest` and `Tag` models:
967

968
```ruby
969
class Category < ActiveRecord::Base
970
  has_many :articles
971 972
end

973
class Article < ActiveRecord::Base
974 975 976 977 978
  belongs_to :category
  has_many :comments
  has_many :tags
end

979
class Comment < ActiveRecord::Base
980
  belongs_to :article
981 982 983 984 985 986
  has_one :guest
end

class Guest < ActiveRecord::Base
  belongs_to :comment
end
987 988

class Tag < ActiveRecord::Base
989
  belongs_to :article
990
end
991
```
992

993
Now all of the following will produce the expected join queries using `INNER JOIN`:
994

995
#### Joining a Single Association
996

997
```ruby
998
Category.joins(:articles)
999
```
1000 1001 1002

This produces:

1003
```sql
1004
SELECT categories.* FROM categories
1005
  INNER JOIN articles ON articles.category_id = categories.id
1006
```
1007

1008
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`.
1009

1010
#### Joining Multiple Associations
1011

1012
```ruby
1013
Article.joins(:category, :comments)
1014
```
1015

1016
This produces:
1017

1018
```sql
1019 1020 1021
SELECT articles.* FROM articles
  INNER JOIN categories ON articles.category_id = categories.id
  INNER JOIN comments ON comments.article_id = articles.id
1022
```
1023

1024
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.
1025

1026
#### Joining Nested Associations (Single Level)
1027

1028
```ruby
1029
Article.joins(comments: :guest)
1030
```
1031

1032 1033
This produces:

1034
```sql
1035 1036
SELECT articles.* FROM articles
  INNER JOIN comments ON comments.article_id = articles.id
1037
  INNER JOIN guests ON guests.comment_id = comments.id
1038
```
1039

1040
Or, in English: "return all articles that have a comment made by a guest."
1041

1042
#### Joining Nested Associations (Multiple Level)
1043

1044
```ruby
1045
Category.joins(articles: [{ comments: :guest }, :tags])
1046
```
1047

1048 1049
This produces:

1050
```sql
1051
SELECT categories.* FROM categories
1052 1053
  INNER JOIN articles ON articles.category_id = categories.id
  INNER JOIN comments ON comments.article_id = articles.id
1054
  INNER JOIN guests ON guests.comment_id = comments.id
1055
  INNER JOIN tags ON tags.article_id = articles.id
1056
```
1057

1058
### Specifying Conditions on the Joined Tables
1059

1060
You can specify conditions on the joined tables using the regular [Array](#array-conditions) and [String](#pure-string-conditions) conditions. [Hash conditions](#hash-conditions) provides a special syntax for specifying conditions for the joined tables:
1061

1062
```ruby
1063
time_range = (Time.now.midnight - 1.day)..Time.now.midnight
1064
Client.joins(:orders).where('orders.created_at' => time_range)
1065
```
1066

1067
An alternative and cleaner syntax is to nest the hash conditions:
1068

1069
```ruby
1070
time_range = (Time.now.midnight - 1.day)..Time.now.midnight
1071
Client.joins(:orders).where(orders: { created_at: time_range })
1072
```
1073

1074
This will find all clients who have orders that were created yesterday, again using a `BETWEEN` SQL expression.
1075

1076 1077
Eager Loading Associations
--------------------------
1078

1079
Eager loading is the mechanism for loading the associated records of the objects returned by `Model.find` using as few queries as possible.
1080

1081
**N + 1 queries problem**
1082 1083 1084

Consider the following code, which finds 10 clients and prints their postcodes:

1085
```ruby
V
Vijay Dev 已提交
1086
clients = Client.limit(10)
1087 1088 1089 1090

clients.each do |client|
  puts client.address.postcode
end
1091
```
1092

1093
This code looks fine at the first sight. But the problem lies within the total number of queries executed. The above code executes 1 (to find 10 clients) + 10 (one per each client to load the address) = **11** queries in total.
1094

1095
**Solution to N + 1 queries problem**
1096

1097
Active Record lets you specify in advance all the associations that are going to be loaded. This is possible by specifying the `includes` method of the `Model.find` call. With `includes`, Active Record ensures that all of the specified associations are loaded using the minimum possible number of queries.
1098

1099
Revisiting the above case, we could rewrite `Client.limit(10)` to use eager load addresses:
1100

1101
```ruby
J
James Miller 已提交
1102
clients = Client.includes(:address).limit(10)
1103 1104 1105 1106

clients.each do |client|
  puts client.address.postcode
end
1107
```
1108

1109
The above code will execute just **2** queries, as opposed to **11** queries in the previous case:
1110

1111
```sql
1112
SELECT * FROM clients LIMIT 10
1113 1114
SELECT addresses.* FROM addresses
  WHERE (addresses.client_id IN (1,2,3,4,5,6,7,8,9,10))
1115
```
1116

1117
### Eager Loading Multiple Associations
1118

1119
Active Record lets you eager load any number of associations with a single `Model.find` call by using an array, hash, or a nested hash of array/hash with the `includes` method.
1120

1121
#### Array of Multiple Associations
1122

1123
```ruby
1124
Article.includes(:category, :comments)
1125
```
1126

1127
This loads all the articles and the associated category and comments for each article.
1128

1129
#### Nested Associations Hash
1130

1131
```ruby
1132
Category.includes(articles: [{ comments: :guest }, :tags]).find(1)
1133
```
1134

1135
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.
1136

1137
### Specifying Conditions on Eager Loaded Associations
1138

1139
Even though Active Record lets you specify conditions on the eager loaded associations just like `joins`, the recommended way is to use [joins](#joining-tables) instead.
1140

1141
However if you must do this, you may use `where` as you would normally.
1142

1143
```ruby
1144
Article.includes(:comments).where(comments: { visible: true })
1145
```
1146

1147 1148
This would generate a query which contains a `LEFT OUTER JOIN` whereas the
`joins` method would generate one using the `INNER JOIN` function instead.
1149

1150
```ruby
1151
  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)
1152
```
1153

1154
If there was no `where` condition, this would generate the normal set of two queries.
1155

1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168
NOTE: Using `where` like this will only work when you pass it a Hash. For
SQL-fragments you need use `references` to force joined tables:

```ruby
Article.includes(:comments).where("comments.visible = true").references(:comments)
```

If, in the case of this `includes` query, there were no comments for any
articles, all the articles would still be loaded. By using `joins` (an INNER
JOIN), the join conditions **must** match, otherwise no records will be
returned.


1169

1170 1171
Scopes
------
1172

1173
Scoping allows you to specify commonly-used queries which can be referenced as method calls on the association objects or models. With these scopes, you can use every method previously covered such as `where`, `joins` and `includes`. All scope methods will return an `ActiveRecord::Relation` object which will allow for further methods (such as other scopes) to be called on it.
1174

1175
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:
1176

1177
```ruby
1178
class Article < ActiveRecord::Base
1179
  scope :published, -> { where(published: true) }
R
Ryan Bigg 已提交
1180
end
1181
```
1182

1183
This is exactly the same as defining a class method, and which you use is a matter of personal preference:
1184

1185
```ruby
1186
class Article < ActiveRecord::Base
1187 1188 1189
  def self.published
    where(published: true)
  end
R
Ryan Bigg 已提交
1190
end
1191
```
1192 1193 1194

Scopes are also chainable within scopes:

1195
```ruby
1196
class Article < ActiveRecord::Base
A
Agis Anastasopoulos 已提交
1197
  scope :published,               -> { where(published: true) }
1198
  scope :published_and_commented, -> { published.where("comments_count > 0") }
R
Ryan Bigg 已提交
1199
end
1200
```
1201

1202
To call this `published` scope we can call it on either the class:
1203

1204
```ruby
1205
Article.published # => [published articles]
1206
```
1207

1208
Or on an association consisting of `Article` objects:
1209

1210
```ruby
R
Ryan Bigg 已提交
1211
category = Category.first
1212
category.articles.published # => [published articles belonging to this category]
1213
```
1214

1215
### Passing in arguments
1216

J
Jon Leighton 已提交
1217
Your scope can take arguments:
1218

1219
```ruby
1220
class Article < ActiveRecord::Base
1221
  scope :created_before, ->(time) { where("created_at < ?", time) }
1222
end
1223
```
1224

1225
Call the scope as if it were a class method:
1226

1227
```ruby
1228
Article.created_before(Time.zone.now)
1229
```
1230 1231 1232

However, this is just duplicating the functionality that would be provided to you by a class method.

1233
```ruby
1234
class Article < ActiveRecord::Base
1235
  def self.created_before(time)
1236 1237 1238
    where("created_at < ?", time)
  end
end
1239
```
1240

1241 1242
Using a class method is the preferred way to accept arguments for scopes. These methods will still be accessible on the association objects:

1243
```ruby
1244
category.articles.created_before(time)
1245
```
1246

1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275
### Applying a default scope

If we wish for a scope to be applied across all queries to the model we can use the
`default_scope` method within the model itself.

```ruby
class Client < ActiveRecord::Base
  default_scope { where("removed_at IS NULL") }
end
```

When queries are executed on this model, the SQL query will now look something like
this:

```sql
SELECT * FROM clients WHERE removed_at IS NULL
```

If you need to do more complex things with a default scope, you can alternatively
define it as a class method:

```ruby
class Client < ActiveRecord::Base
  def self.default_scope
    # Should return an ActiveRecord::Relation.
  end
end
```

1276 1277 1278 1279 1280 1281 1282
### Merging of scopes

Just like `where` clauses scopes are merged using `AND` conditions.

```ruby
class User < ActiveRecord::Base
  scope :active, -> { where state: 'active' }
1283
  scope :inactive, -> { where state: 'inactive' }
1284 1285 1286
end

User.active.inactive
1287
# SELECT "users".* FROM "users" WHERE "users"."state" = 'active' AND "users"."state" = 'inactive'
1288 1289 1290
```

We can mix and match `scope` and `where` conditions and the final sql
R
Rafael Mendonça França 已提交
1291
will have all conditions joined with `AND`.
1292 1293 1294

```ruby
User.active.where(state: 'finished')
1295
# SELECT "users".* FROM "users" WHERE "users"."state" = 'active' AND "users"."state" = 'finished'
1296 1297 1298
```

If we do want the `last where clause` to win then `Relation#merge` can
R
Rafael Mendonça França 已提交
1299
be used.
1300 1301 1302

```ruby
User.active.merge(User.inactive)
1303
# SELECT "users".* FROM "users" WHERE "users"."state" = 'inactive'
1304 1305
```

1306
One important caveat is that `default_scope` will be prepended in
1307 1308 1309 1310
`scope` and `where` conditions.

```ruby
class User < ActiveRecord::Base
1311
  default_scope { where state: 'pending' }
1312
  scope :active, -> { where state: 'active' }
1313
  scope :inactive, -> { where state: 'inactive' }
1314 1315 1316
end

User.all
1317
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending'
1318 1319

User.active
1320
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending' AND "users"."state" = 'active'
1321 1322

User.where(state: 'inactive')
1323
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending' AND "users"."state" = 'inactive'
1324 1325
```

1326
As you can see above the `default_scope` is being merged in both
V
Vijay Dev 已提交
1327
`scope` and `where` conditions.
1328

1329
### Removing All Scoping
1330

1331 1332
If we wish to remove scoping for any reason we can use the `unscoped` method. This is
especially useful if a `default_scope` is specified in the model and should not be
1333
applied for this particular query.
1334

1335
```ruby
1336
Client.unscoped.load
1337
```
1338 1339 1340

This method removes all scoping and will do a normal query on the table.

1341 1342
Note that chaining `unscoped` with a `scope` does not work. In these cases, it is
recommended that you use the block form of `unscoped`:
1343

1344
```ruby
1345
Client.unscoped {
V
Vipul A M 已提交
1346
  Client.created_before(Time.zone.now)
1347
}
1348
```
1349

1350 1351
Dynamic Finders
---------------
1352

1353
For every field (also known as an attribute) you define in your table, Active Record provides a finder method. If you have a field called `first_name` on your `Client` model for example, you get `find_by_first_name` for free from Active Record. If you have a `locked` field on the `Client` model, you also get `find_by_locked` and methods.
1354

1355
You can specify an exclamation point (`!`) on the end of the dynamic finders to get them to raise an `ActiveRecord::RecordNotFound` error if they do not return any records, like `Client.find_by_name!("Ryan")`
1356

1357
If you want to find both by name and locked, you can chain these finders together by simply typing "`and`" between the fields. For example, `Client.find_by_first_name_and_locked("Ryan", true)`.
1358

1359
Find or Build a New Object
1360
--------------------------
1361

1362 1363 1364 1365 1366
NOTE: Some dynamic finders have been deprecated in Rails 4.0 and will be
removed in Rails 4.1. The best practice is to use Active Record scopes
instead. You can find the deprecation gem at
https://github.com/rails/activerecord-deprecated_finders

1367
It's common that you need to find a record or create it if it doesn't exist. You can do that with the `find_or_create_by` and `find_or_create_by!` methods.
1368

1369
### `find_or_create_by`
1370

1371
The `find_or_create_by` method checks whether a record with the attributes exists. If it doesn't, then `create` is called. Let's see an example.
1372

1373
Suppose you want to find a client named 'Andy', and if there's none, create one. You can do so by running:
1374

1375
```ruby
1376 1377
Client.find_or_create_by(first_name: 'Andy')
# => #<Client id: 1, first_name: "Andy", orders_count: 0, locked: true, created_at: "2011-08-30 06:09:27", updated_at: "2011-08-30 06:09:27">
1378
```
1379 1380

The SQL generated by this method looks like this:
1381

1382
```sql
1383
SELECT * FROM clients WHERE (clients.first_name = 'Andy') LIMIT 1
1384
BEGIN
1385
INSERT INTO clients (created_at, first_name, locked, orders_count, updated_at) VALUES ('2011-08-30 05:22:57', 'Andy', 1, NULL, '2011-08-30 05:22:57')
1386
COMMIT
1387
```
1388

1389
`find_or_create_by` returns either the record that already exists or the new record. In our case, we didn't already have a client named Andy so the record is created and returned.
1390

1391
The new record might not be saved to the database; that depends on whether validations passed or not (just like `create`).
1392

1393
Suppose we want to set the 'locked' attribute to `false` if we're
1394 1395 1396
creating a new record, but we don't want to include it in the query. So
we want to find the client named "Andy", or if that client doesn't
exist, create a client named "Andy" which is not locked.
1397

1398
We can achieve this in two ways. The first is to use `create_with`:
1399 1400 1401 1402 1403 1404

```ruby
Client.create_with(locked: false).find_or_create_by(first_name: 'Andy')
```

The second way is using a block:
1405

1406
```ruby
1407 1408 1409 1410 1411 1412 1413 1414
Client.find_or_create_by(first_name: 'Andy') do |c|
  c.locked = false
end
```

The block will only be executed if the client is being created. The
second time we run this code, the block will be ignored.

1415
### `find_or_create_by!`
1416 1417

You can also use `find_or_create_by!` to raise an exception if the new record is invalid. Validations are not covered on this guide, but let's assume for a moment that you temporarily add
1418

1419
```ruby
A
Agis Anastasopoulos 已提交
1420
validates :orders_count, presence: true
1421
```
1422

1423
to your `Client` model. If you try to create a new `Client` without passing an `orders_count`, the record will be invalid and an exception will be raised:
1424

1425
```ruby
1426
Client.find_or_create_by!(first_name: 'Andy')
1427
# => ActiveRecord::RecordInvalid: Validation failed: Orders count can't be blank
1428
```
1429

1430
### `find_or_initialize_by`
1431

1432 1433 1434 1435 1436
The `find_or_initialize_by` method will work just like
`find_or_create_by` but it will call `new` instead of `create`. This
means that a new model instance will be created in memory but won't be
saved to the database. Continuing with the `find_or_create_by` example, we
now want the client named 'Nick':
1437

1438
```ruby
1439 1440
nick = Client.find_or_initialize_by(first_name: 'Nick')
# => <Client id: nil, first_name: "Nick", orders_count: 0, locked: true, created_at: "2011-08-30 06:09:27", updated_at: "2011-08-30 06:09:27">
1441 1442

nick.persisted?
1443
# => false
1444 1445

nick.new_record?
1446
# => true
1447
```
1448 1449 1450

Because the object is not yet stored in the database, the SQL generated looks like this:

1451
```sql
1452
SELECT * FROM clients WHERE (clients.first_name = 'Nick') LIMIT 1
1453
```
1454

1455
When you want to save it to the database, just call `save`:
1456

1457
```ruby
1458
nick.save
1459
# => true
1460
```
1461

1462 1463
Finding by SQL
--------------
1464

1465
If you'd like to use your own SQL to find records in a table you can use `find_by_sql`. The `find_by_sql` method will return an array of objects even if the underlying query returns just a single record. For example you could run this query:
1466

1467
```ruby
1468 1469
Client.find_by_sql("SELECT * FROM clients
  INNER JOIN orders ON clients.id = orders.client_id
1470
  ORDER BY clients.created_at desc")
1471 1472 1473 1474 1475
# =>  [
  #<Client id: 1, first_name: "Lucas" >,
  #<Client id: 2, first_name: "Jan" >,
  # ...
]
1476
```
1477

1478
`find_by_sql` provides you with a simple way of making custom calls to the database and retrieving instantiated objects.
1479

1480
### `select_all`
1481

1482
`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.
1483

1484
```ruby
1485 1486 1487 1488 1489
Client.connection.select_all("SELECT first_name, created_at FROM clients WHERE id = '1'")
# => [
  {"first_name"=>"Rafael", "created_at"=>"2012-11-10 23:23:45.281189"},
  {"first_name"=>"Eileen", "created_at"=>"2013-12-09 11:22:35.221282"}
]
1490
```
1491

1492
### `pluck`
1493

1494
`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.
1495

1496
```ruby
A
Agis Anastasopoulos 已提交
1497
Client.where(active: true).pluck(:id)
V
Vijay Dev 已提交
1498
# SELECT id FROM clients WHERE active = 1
1499
# => [1, 2, 3]
V
Vijay Dev 已提交
1500

1501
Client.distinct.pluck(:role)
V
Vijay Dev 已提交
1502
# SELECT DISTINCT role FROM clients
1503 1504 1505 1506 1507
# => ['admin', 'member', 'guest']

Client.pluck(:id, :name)
# SELECT clients.id, clients.name FROM clients
# => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]
1508
```
V
Vijay Dev 已提交
1509

1510
`pluck` makes it possible to replace code like:
V
Vijay Dev 已提交
1511

1512
```ruby
V
Vijay Dev 已提交
1513
Client.select(:id).map { |c| c.id }
1514
# or
1515 1516
Client.select(:id).map(&:id)
# or
1517
Client.select(:id, :name).map { |c| [c.id, c.name] }
1518
```
V
Vijay Dev 已提交
1519

1520
with:
V
Vijay Dev 已提交
1521

1522
```ruby
V
Vijay Dev 已提交
1523
Client.pluck(:id)
1524 1525
# or
Client.pluck(:id, :name)
1526
```
1527

1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558
Unlike `select`, `pluck` directly converts a database result into a Ruby `Array`,
without constructing `ActiveRecord` objects. This can mean better performance for
a large or often-running query. However, any model method overrides will
not be available. For example:

```ruby
class Client < ActiveRecord::Base
  def name
    "I am #{super}"
  end
end

Client.select(:name).map &:name
# => ["I am David", "I am Jeremy", "I am Jose"]

Client.pluck(:name)
# => ["David", "Jeremy", "Jose"]
```

Furthermore, unlike `select` and other `Relation` scopes, `pluck` triggers an immediate
query, and thus cannot be chained with any further scopes, although it can work with
scopes already constructed earlier:

```ruby
Client.pluck(:name).limit(1)
# => NoMethodError: undefined method `limit' for #<Array:0x007ff34d3ad6d8>

Client.limit(1).pluck(:name)
# => ["David"]
```

1559
### `ids`
1560

1561
`ids` can be used to pluck all the IDs for the relation using the table's primary key.
1562

1563
```ruby
1564 1565
Person.ids
# SELECT id FROM people
1566
```
1567

1568
```ruby
1569 1570 1571 1572 1573 1574
class Person < ActiveRecord::Base
  self.primary_key = "person_id"
end

Person.ids
# SELECT person_id FROM people
1575
```
1576

1577 1578
Existence of Objects
--------------------
1579

1580 1581 1582
If you simply want to check for the existence of the object there's a method called `exists?`.
This method will query the database using the same query as `find`, but instead of returning an
object or collection of objects it will return either `true` or `false`.
1583

1584
```ruby
1585
Client.exists?(1)
1586
```
1587

1588 1589
The `exists?` method also takes multiple values, but the catch is that it will return `true` if any
one of those records exists.
1590

1591
```ruby
1592
Client.exists?(id: [1,2,3])
1593
# or
1594
Client.exists?(name: ['John', 'Sergei'])
1595
```
1596

1597
It's even possible to use `exists?` without any arguments on a model or a relation.
1598

1599
```ruby
A
Agis Anastasopoulos 已提交
1600
Client.where(first_name: 'Ryan').exists?
1601
```
1602

1603 1604
The above returns `true` if there is at least one client with the `first_name` 'Ryan' and `false`
otherwise.
P
Pratik Naik 已提交
1605

1606
```ruby
P
Pratik Naik 已提交
1607
Client.exists?
1608
```
P
Pratik Naik 已提交
1609

1610
The above returns `false` if the `clients` table is empty and `true` otherwise.
P
Pratik Naik 已提交
1611

1612
You can also use `any?` and `many?` to check for existence on a model or relation.
1613

1614
```ruby
1615
# via a model
1616 1617
Article.any?
Article.many?
1618 1619

# via a named scope
1620 1621
Article.recent.any?
Article.recent.many?
1622 1623

# via a relation
1624 1625
Article.where(published: true).any?
Article.where(published: true).many?
1626 1627

# via an association
1628 1629
Article.first.categories.any?
Article.first.categories.many?
1630
```
1631

1632 1633
Calculations
------------
1634 1635 1636

This section uses count as an example method in this preamble, but the options described apply to all sub-sections.

P
Pratik Naik 已提交
1637
All calculation methods work directly on a model:
1638

1639
```ruby
P
Pratik Naik 已提交
1640 1641
Client.count
# SELECT count(*) AS count_all FROM clients
1642
```
1643

M
Matt Duncan 已提交
1644
Or on a relation:
1645

1646
```ruby
A
Agis Anastasopoulos 已提交
1647
Client.where(first_name: 'Ryan').count
P
Pratik Naik 已提交
1648
# SELECT count(*) AS count_all FROM clients WHERE (first_name = 'Ryan')
1649
```
1650

P
Pratik Naik 已提交
1651
You can also use various finder methods on a relation for performing complex calculations:
1652

1653
```ruby
1654
Client.includes("orders").where(first_name: 'Ryan', orders: { status: 'received' }).count
1655
```
1656 1657 1658

Which will execute:

1659
```sql
1660 1661 1662
SELECT count(DISTINCT clients.id) AS count_all FROM clients
  LEFT OUTER JOIN orders ON orders.client_id = client.id WHERE
  (clients.first_name = 'Ryan' AND orders.status = 'received')
1663
```
1664

1665
### Count
1666

1667
If you want to see how many records are in your model's table you could call `Client.count` and that will return the number. If you want to be more specific and find all the clients with their age present in the database you can use `Client.count(:age)`.
1668

1669
For options, please see the parent section, [Calculations](#calculations).
1670

1671
### Average
1672

1673
If you want to see the average of a certain number in one of your tables you can call the `average` method on the class that relates to the table. This method call will look something like this:
1674

1675
```ruby
1676
Client.average("orders_count")
1677
```
1678 1679 1680

This will return a number (possibly a floating point number such as 3.14159265) representing the average value in the field.

1681
For options, please see the parent section, [Calculations](#calculations).
1682

1683
### Minimum
1684

1685
If you want to find the minimum value of a field in your table you can call the `minimum` method on the class that relates to the table. This method call will look something like this:
1686

1687
```ruby
1688
Client.minimum("age")
1689
```
1690

1691
For options, please see the parent section, [Calculations](#calculations).
1692

1693
### Maximum
1694

1695
If you want to find the maximum value of a field in your table you can call the `maximum` method on the class that relates to the table. This method call will look something like this:
1696

1697
```ruby
1698
Client.maximum("age")
1699
```
1700

1701
For options, please see the parent section, [Calculations](#calculations).
1702

1703
### Sum
1704

1705
If you want to find the sum of a field for all records in your table you can call the `sum` method on the class that relates to the table. This method call will look something like this:
1706

1707
```ruby
1708
Client.sum("orders_count")
1709
```
1710

1711
For options, please see the parent section, [Calculations](#calculations).
X
Xavier Noria 已提交
1712

1713 1714
Running EXPLAIN
---------------
X
Xavier Noria 已提交
1715 1716 1717

You can run EXPLAIN on the queries triggered by relations. For example,

1718
```ruby
1719
User.where(id: 1).joins(:articles).explain
1720
```
X
Xavier Noria 已提交
1721 1722 1723

may yield

1724
```
1725
EXPLAIN for: SELECT `users`.* FROM `users` INNER JOIN `articles` ON `articles`.`user_id` = `users`.`id` WHERE `users`.`id` = 1
1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738
+----+-------------+----------+-------+---------------+
| id | select_type | table    | type  | possible_keys |
+----+-------------+----------+-------+---------------+
|  1 | SIMPLE      | users    | const | PRIMARY       |
|  1 | SIMPLE      | articles | ALL   | NULL          |
+----+-------------+----------+-------+---------------+
+---------+---------+-------+------+-------------+
| key     | key_len | ref   | rows | Extra       |
+---------+---------+-------+------+-------------+
| PRIMARY | 4       | const |    1 |             |
| NULL    | NULL    | NULL  |    1 | Using where |
+---------+---------+-------+------+-------------+

X
Xavier Noria 已提交
1739
2 rows in set (0.00 sec)
1740
```
X
Xavier Noria 已提交
1741 1742 1743 1744

under MySQL.

Active Record performs a pretty printing that emulates the one of the database
V
Vijay Dev 已提交
1745
shells. So, the same query running with the PostgreSQL adapter would yield instead
X
Xavier Noria 已提交
1746

1747
```
1748
EXPLAIN for: SELECT "users".* FROM "users" INNER JOIN "articles" ON "articles"."user_id" = "users"."id" WHERE "users"."id" = 1
X
Xavier Noria 已提交
1749 1750 1751
                                  QUERY PLAN
------------------------------------------------------------------------------
 Nested Loop Left Join  (cost=0.00..37.24 rows=8 width=0)
1752
   Join Filter: (articles.user_id = users.id)
X
Xavier Noria 已提交
1753 1754
   ->  Index Scan using users_pkey on users  (cost=0.00..8.27 rows=1 width=4)
         Index Cond: (id = 1)
1755 1756
   ->  Seq Scan on articles  (cost=0.00..28.88 rows=8 width=4)
         Filter: (articles.user_id = 1)
X
Xavier Noria 已提交
1757
(6 rows)
1758
```
X
Xavier Noria 已提交
1759 1760

Eager loading may trigger more than one query under the hood, and some queries
1761
may need the results of previous ones. Because of that, `explain` actually
X
Xavier Noria 已提交
1762 1763
executes the query, and then asks for the query plans. For example,

1764
```ruby
1765
User.where(id: 1).includes(:articles).explain
1766
```
X
Xavier Noria 已提交
1767 1768 1769

yields

1770
```
1771
EXPLAIN for: SELECT `users`.* FROM `users`  WHERE `users`.`id` = 1
1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782
+----+-------------+-------+-------+---------------+
| id | select_type | table | type  | possible_keys |
+----+-------------+-------+-------+---------------+
|  1 | SIMPLE      | users | const | PRIMARY       |
+----+-------------+-------+-------+---------------+
+---------+---------+-------+------+-------+
| key     | key_len | ref   | rows | Extra |
+---------+---------+-------+------+-------+
| PRIMARY | 4       | const |    1 |       |
+---------+---------+-------+------+-------+

X
Xavier Noria 已提交
1783
1 row in set (0.00 sec)
1784

1785
EXPLAIN for: SELECT `articles`.* FROM `articles`  WHERE `articles`.`user_id` IN (1)
1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797
+----+-------------+----------+------+---------------+
| id | select_type | table    | type | possible_keys |
+----+-------------+----------+------+---------------+
|  1 | SIMPLE      | articles | ALL  | NULL          |
+----+-------------+----------+------+---------------+
+------+---------+------+------+-------------+
| key  | key_len | ref  | rows | Extra       |
+------+---------+------+------+-------------+
| NULL | NULL    | NULL |    1 | Using where |
+------+---------+------+------+-------------+


X
Xavier Noria 已提交
1798
1 row in set (0.00 sec)
1799
```
X
Xavier Noria 已提交
1800 1801

under MySQL.
1802

1803
### Interpreting EXPLAIN
1804 1805 1806 1807

Interpretation of the output of EXPLAIN is beyond the scope of this guide. The
following pointers may be helpful:

1808
* SQLite3: [EXPLAIN QUERY PLAN](http://www.sqlite.org/eqp.html)
1809

1810
* MySQL: [EXPLAIN Output Format](http://dev.mysql.com/doc/refman/5.6/en/explain-output.html)
1811

1812
* PostgreSQL: [Using EXPLAIN](http://www.postgresql.org/docs/current/static/using-explain.html)