First vs take vs Limit methods in Rails
Last updated on December 20, 2021
There are some notable differences between the #take, #first & #limit methods that we, as Rails developers, should be aware of.
The Take method returns a record without any implied order. You can also specify a parameter, for example, #take(5) which will return the number of records you have specified in your parameter.
#take generates the following SQL
1> User.take2User Load (0.5ms) SELECT "users".* FROM "users" LIMIT $1 [["LIMIT", 1]]34> User.take(5)5User Load (0.5ms) SELECT "users".* FROM "users" LIMIT $1 [["LIMIT", 5]]
The order is indeed random
1> User.take(5).map(&:id)2User Load (0.6ms) SELECT "users".* FROM "users" LIMIT $1 [["LIMIT", 5]]3=> [2, 108, 37, 487, 20]
If you don't care about the order or if you want an arbitrary record, #take is a good way to go.
Notice that #take is also an array method which works in a slightly different way. If you call Array#take, a parameter is required and it returns the first N records in the form of an array.
Therefore, User.take(5).take(1) is a valid syntax but User.take(5).take will throws an error.
The First method is similar to #take, but it returns the first record (or N records if a parameter is specified).
#first generates the SQL
1> User.first2User Load (10.6ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]3> User.first(5)4User Load (0.6ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 5]]
Notice that the #first adds an additional ordering query to the SQL command. This means that in general #take will be faster than #first since #take can stop as soon as it finds the first row. The difference often might be negligible, but if you don't need the first record just, I recommend you to just use #take.
Just like #take, #first also has its array version. It works very similarly its Rails version and as well as Array#take.
Array#first doesn't require an argument, unlike Array#take. You should also note that Array#first(1) will return an array unlike Array#first, which will return a single value.
Another difference can be found when you call the methods on empty arrays
1> .take(1)2=> 34> .first5=> nil
You should decide which behaviour you want in a given scenario within your app.
The Limit method specifies a limit for the number of records to retrieve. Unlike the previous two methods, #limit requires a parameter. It always returns an Active Record Relation.
#limit generates the SQL
1> User.limit(5)2User Load (0.5ms) SELECT "users".* FROM "users" LIMIT $1 [["LIMIT", 5]]3> User.limit(5).class4=> User::ActiveRecord_Relation
Since #limit returns an Active Record Relation, this means that you can continue scoping afterwards
1> User.limit(5).where(id: 1)2User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 5]]
This won't work with either #take or #first because these methods return an array. Therefore, an error will be thrown at you.
Limit does not have a corresponding Array method, so if you call it on an Array, it will throw an error.
Level up your web development skills
Get articles, guides and interviews right in your inbox. Join a community of fellow developers.
No spam. Unsubscribe at any time.