ruby-on-rails - query - rails find
¿Cómo obtener los últimos N registros con activerecord? (13)
Con :limit
en la consulta, obtendré los primeros N registros. ¿Cuál es la forma más fácil de obtener los últimos N registros?
Para Rails 5 (y probablemente Rails 4)
Malo:
Something.last(5)
porque:
Something.last(5).class
=> Array
asi que:
Something.last(50000).count
probablemente hará explotar tu memoria o demorará para siempre.
Buen enfoque:
Something.limit(5).order(''id desc'')
porque:
Something.limit(5).order(''id desc'').class
=> Image::ActiveRecord_Relation
Something.limit(5).order(''id desc'').to_sql
=> "SELECT /"somethings/".* FROM /"somethings/" ORDER BY id desc LIMIT 5"
Este último es un alcance no evaluado. Puede encadenarlo o convertirlo en una matriz a través de .to_a
. Asi que:
Something.limit(50000).order(''id desc'').count
... toma un segundo.
Agregar un: parámetro de orden a la consulta
Digamos que N = 5 y su modelo es Message
, puede hacer algo como esto:
Message.order(id: :asc).from(Message.all.order(id: :desc).limit(5), :messages)
Mira el sql:
SELECT "messages".* FROM (
SELECT "messages".* FROM "messages" ORDER BY "messages"."created_at" DESC LIMIT 5
) messages ORDER BY "messages"."created_at" ASC
La clave es la subselección. Primero debemos definir cuáles son los últimos mensajes que queremos y luego tenemos que ordenarlos en orden ascendente.
En mi proyecto de carriles (rails 4.2)
, uso
Model.last(10) # get the last 10 record order by id
y funciona.
Encuentro que esta consulta es mejor / más rápida para usar el método "desplume", que me encanta:
Challenge.limit(5).order(''id desc'')
Esto da un ActiveRecord como salida; para que puedas usar .pluck en él así:
Challenge.limit(5).order(''id desc'').pluck(:id)
que rápidamente proporciona los identificadores como una matriz al usar un código SQL óptimo.
Esta es la forma de Rails 3
SomeModel.last(5) # last 5 records in ascending order
SomeModel.last(5).reverse # last 5 records in descending order
La nueva forma de hacerlo en rails 3.1 es SomeModel.limit(5).order(''id desc'')
La solución está aquí:
SomeModel.last(5).reverse
Como los rieles son flojos, eventualmente llegarán a la base de datos con SQL como: "SELECT table
. * FROM table
ORDER BY table
. id
DESC LIMIT 5".
Para la versión Rails 4 y superior:
Puedes intentar algo como esto si quieres la primera entrada más antigua
YourModel.order(id: :asc).limit(5).each do |d|
Puede intentar algo como esto si quiere las últimas entradas más recientes .
YourModel.order(id: :desc).limit(5).each do |d|
Sólo inténtalo:
Model.all.order("id asc").limit(5)
Si necesita establecer algún orden en los resultados, use:
Model.order(''name desc'').limit(n) # n= number
si no necesita ningún pedido, y solo necesita registros guardados en la tabla, utilice:
Model.last(n) # n= any number
Si tiene un alcance predeterminado en su modelo que especifica un orden ascendente en Rails 3, deberá usar el orden en lugar del pedido según lo especificado por Arthur Neves arriba:
Something.limit(5).reorder(''id desc'')
o
Something.reorder(''id desc'').limit(5)
Una consulta de registro activa como esta creo que obtendría lo que desea (''Algo'' es el nombre del modelo):
Something.find(:all, :order => "id desc", :limit => 5).reverse
editar : Como se señaló en los comentarios, de otra manera:
result = Something.find(:all, :order => "id desc", :limit => 5)
while !result.empty?
puts result.pop
end