ActiveRecord frist,take,limitの違い
今回はfirst,take,limitの挙動の違いに躓きましたのでまとめました。
間違いなどありましたら、ご教示頂けますと幸いです。
first
前提としてUserクラスが存在するとします。
クエリを見てみると・・・
pry(main)> user = User.first User Load (0.7ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
orderされています!!!
pry(main)> User.pluck(:id,:name) => [[2, "田中"], [1, "佐藤"]] pry(main)> user.first.id => 1 pry(main)> user.first.name => '佐藤'
ですので、レコードのIDが昇順になっていなくてもorderしてくれるので最もidが若いものを取得できています。
take
pry(main)> user = User.take User Load (0.7ms) SELECT "users".* FROM "users" LIMIT $1 [["LIMIT", 1]]
first
のようにorderはされていません。
pry(main)> User.pluck(:id,:name) => [[2, "田中"], [1, "佐藤"]] pry(main)> user.first.id => 2 pry(main)> user.first.name => '田中'
ですので、DBの先頭に保存されているレコードがそのまま取得されてしまいます。
limit
pry(main)> user = User.limit(1) => User Load (0.4ms) SELECT "users".* FROM "users" LIMIT $1 [["LIMIT", 1]]
limit
は引数を指定しないと使えません。
pry(main)> User.pluck(:id,:name) => [[2, "田中"], [1, "佐藤"]] pry(main)> user.first.id => 2 pry(main)> user.first.name => '田中'
また、limit
もtake
と同じようにorderはしてくれません
pry(main)> User.limit(1).class => User::ActiveRecord_Relation
ただfirst
やtake
と異なるのがlimit
は、返り値がActiveRecord_Relation
になります。
scopeなどでメソッドチェーンをしたいときは、limit
の方がいいかもしれません。