4.4. first, last and all

In certain cases, you may need the first record, or the last one, or perhaps even all records. Conveniently, there is a ready-made method for each case. Let's start with the easiest ones: first and last.
$ rails console
Loading development environment (Rails 4.0.0)
>> Country.first
  Country Load (0.1ms)  SELECT "countries".* FROM "countries" ORDER BY "countries"."id" ASC LIMIT 1
=> #<Country id: 1, name: "Germany", population: 81831000, created_at: "2013-07-15 18:03:20", updated_at: "2013-07-15 18:03:20">
>> Country.last
  Country Load (0.3ms)  SELECT "countries".* FROM "countries" ORDER BY "countries"."id" DESC LIMIT 1
=> #<Country id: 4, name: "Netherlands", population: nil, created_at: "2013-07-15 18:08:52", updated_at: "2013-07-15 18:08:52">
>>
And now all at once with all:
>> Country.all
  Country Load (0.2ms)  SELECT "countries".* FROM "countries"
=> #<ActiveRecord::Relation [#<Country id: 1, name: "Germany", population: 81831000, created_at: "2013-07-15 18:03:20", updated_at: "2013-07-15 18:03:20">, #<Country id: 2, name: "France", population: 65447374, created_at: "2013-07-15 18:07:03", updated_at: "2013-07-15 18:07:03">, #<Country id: 3, name: "Belgium", population: 10839905, created_at: "2013-07-15 18:08:07", updated_at: "2013-07-15 18:08:07">, #<Country id: 4, name: "Netherlands", population: nil, created_at: "2013-07-15 18:08:52", updated_at: "2013-07-15 18:08:52">]>
>>
But the objects created by first, last and all are different. first and last return an object of the class Country and all of course returns an array of such objects:
>> Country.first.class
  Country Load (0.3ms)  SELECT "countries".* FROM "countries" ORDER BY "countries"."id" ASC LIMIT 1
=> Country(id: integer, name: string, population: integer, created_at: datetime, updated_at: datetime)
>> Country.all.class
=> ActiveRecord::Relation::ActiveRecord_Relation_Country
>>
So Country.first is a Country which makes sense. But Country.all is something we haven't had yet. Let's use the console to get a better idea of it:
>> puts Country.all.to_yaml
  Country Load (0.4ms)  SELECT "countries".* FROM "countries"
---
- !ruby/object:Country
  attributes:
    id: 1
    name: Germany
    population: 81831000
    created_at: 2013-07-15 18:03:20.814776000 Z
    updated_at: 2013-07-15 18:03:20.814776000 Z
- !ruby/object:Country
  attributes:
    id: 2
    name: France
    population: 65447374
    created_at: 2013-07-15 18:07:03.227571000 Z
    updated_at: 2013-07-15 18:07:03.227571000 Z
- !ruby/object:Country
  attributes:
    id: 3
    name: Belgium
    population: 10839905
    created_at: 2013-07-15 18:08:07.125974000 Z
    updated_at: 2013-07-15 18:08:07.125974000 Z
- !ruby/object:Country
  attributes:
    id: 4
    name: Netherlands
    population: 
    created_at: 2013-07-15 18:08:52.736007000 Z
    updated_at: 2013-07-15 18:08:52.736007000 Z
=> nil
>>
hmmm... by using the to_yaml method suddenly the database has work to do. The reason for this behavior is optimization. Let's assume that you want to chain a couple of methods. Than it might be better for ActiveRecord to wait till the very last second which it does. It only requests the data from the SQL database when it has to do it. Until than it stores the request in a ActiveRecord::Relation.
The result of Country.all is actually an Array of Country.
If Country.all returns an array, then we should also be able to use iterators (see the section called “Iterators” and the section called “Iterator each”), right? Yes, of course! That is the beauty of it. Here is a little experiment with each:
>> Country.all.each do |country|
?> puts country.name
>> end
  Country Load (0.3ms)  SELECT "countries".* FROM "countries"
Germany
France
Belgium
Netherlands
=> [#<Country id: 1, name: "Germany", population: 81831000, created_at: "2013-07-15 18:03:20", updated_at: "2013-07-15 18:03:20">, #<Country id: 2, name: "France", population: 65447374, created_at: "2013-07-15 18:07:03", updated_at: "2013-07-15 18:07:03">, #<Country id: 3, name: "Belgium", population: 10839905, created_at: "2013-07-15 18:08:07", updated_at: "2013-07-15 18:08:07">, #<Country id: 4, name: "Netherlands", population: nil, created_at: "2013-07-15 18:08:52", updated_at: "2013-07-15 18:08:52">]
>> 
So can we also use .all.first as an alternative for .first? Yes, but it does not make much sense. Have a look for yourself:
>> Country.first
  Country Load (0.3ms)  SELECT "countries".* FROM "countries" ORDER BY "countries"."id" ASC LIMIT 1
=> #<Country id: 1, name: "Germany", population: 81831000, created_at: "2013-07-15 18:03:20", updated_at: "2013-07-15 18:03:20">
>> Country.all.first
  Country Load (0.4ms)  SELECT "countries".* FROM "countries" ORDER BY "countries"."id" ASC LIMIT 1
=> #<Country id: 1, name: "Germany", population: 81831000, created_at: "2013-07-15 18:03:20", updated_at: "2013-07-15 18:03:20">
>> 
Country.first and Country.all.first result in exact the same SQL query.