Câu trả lời:
Một truy vấn bản ghi hoạt động như thế này tôi nghĩ sẽ mang lại cho bạn những gì bạn muốn ('Cái gì đó' là tên mô hình):
Something.find(:all, :order => "id desc", :limit => 5).reverse
chỉnh sửa : Như đã lưu ý trong các ý kiến, một cách khác:
result = Something.find(:all, :order => "id desc", :limit => 5)
while !result.empty?
puts result.pop
end
Đây là cách 3 đường ray
SomeModel.last(5) # last 5 records in ascending order
SomeModel.last(5).reverse # last 5 records in descending order
SELECT "items".* FROM "items" ORDER BY id DESC LIMIT 50
SomeModel.last(5).class
== Array
. Cách tiếp cận đúng là SomeModel.limit(5).order('id desc')
theo Arthur Neves, kết quả làSELECT \"somemodels\".* FROM \"somemodels\" ORDER BY id desc LIMIT 5
cách mới để làm điều đó trong đường ray 3.1 là SomeModel.limit(5).order('id desc')
last(5)
bởi vì nó trả về một phạm vi cho chuỗi tiếp theo.
SomeModel.limit(100).reverse_order
trên Rails 4 ( guide.rubyonrails.org/ - ) Nó giống nhau.
SomeModel.limit(5).order('id desc').pluck(:col)
sẽ làm SELECT SomeModel.col FROM SomeModel ORDER BY id desc LIMIT 5
đó là hiệu quả hơn so với lấy tất cả các cột và loại bỏ tất cả nhưng một cột với SomeModel.last(5).map(&:col)
mà không SELECT *
thay vì SELECT col
(bạn có thể không nhổ sau khi gọi cuối cùng, chuỗi lười biếng kết thúc với cuối cùng).
Something.last(5)
bởi vì:
Something.last(5).class
=> Array
vì thế:
Something.last(50000).count
sẽ có khả năng làm nổ tung bộ nhớ của bạn hoặc mất mãi mãi.
Something.limit(5).order('id desc')
bởi vì:
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"
Cái sau là một phạm vi không được đánh giá. Bạn có thể xâu chuỗi nó, hoặc chuyển đổi nó thành một mảng thông qua .to_a
. Vì thế:
Something.limit(50000).order('id desc').count
... Mất một giây.
Đối với phiên bản Rails 4 trở lên:
Bạn có thể thử một cái gì đó như thế này Nếu bạn muốn mục cũ nhất đầu tiên
YourModel.order(id: :asc).limit(5).each do |d|
Bạn có thể thử một cái gì đó như thế này nếu bạn muốn các mục mới nhất ..
YourModel.order(id: :desc).limit(5).each do |d|
YourModel.all.order(id: :desc).limit(5)
" "
YourModel.all.order()
vì giống nhưYourModel.order()
Giải pháp là đây:
SomeModel.last(5).reverse
Vì đường ray là lười biếng, cuối cùng nó sẽ tấn công cơ sở dữ liệu bằng SQL như: "CHỌN table
. * TỪ table
ĐẶT HÀNG B .NG table
. id
GIỚI HẠN MÔ TẢ 5".
SomeModel
SELECT
bảng .* FROM
bảng` ĐẶT HÀNG B .NG table
.id
GIỚI HẠN DESC 5` nó không thực hiện chọn tất cả
chúng ta có thể sử dụng Model.last(5)
hoặc Model.limit(5).order(id: :desc)
trong đường ray 5.2
Tôi thấy rằng truy vấn này tốt hơn / nhanh hơn khi sử dụng phương pháp "nhổ" mà tôi yêu thích:
Challenge.limit(5).order('id desc')
Điều này cung cấp cho ActiveRecord làm đầu ra; vì vậy bạn có thể sử dụng .pluck trên nó như thế này:
Challenge.limit(5).order('id desc').pluck(:id)
mà nhanh chóng cung cấp cho các id dưới dạng một mảng trong khi sử dụng mã SQL tối ưu.
Challenge.limit(5).order('id desc').ids
sẽ hoạt động tốt như vậy :)
Nếu bạn có phạm vi mặc định trong mô hình của mình chỉ định thứ tự tăng dần trong Rails 3, bạn sẽ cần sử dụng sắp xếp lại thay vì đặt hàng theo quy định của Arthur Neves ở trên:
Something.limit(5).reorder('id desc')
hoặc là
Something.reorder('id desc').limit(5)
Giả sử N = 5 và mô hình của bạn là Message
, bạn có thể làm một cái gì đó như thế này:
Message.order(id: :asc).from(Message.all.order(id: :desc).limit(5), :messages)
Nhìn vào sql:
SELECT "messages".* FROM (
SELECT "messages".* FROM "messages" ORDER BY "messages"."created_at" DESC LIMIT 5
) messages ORDER BY "messages"."created_at" ASC
Điều quan trọng là subselect. Đầu tiên chúng ta cần xác định những thông điệp cuối cùng chúng ta muốn là gì và sau đó chúng ta phải sắp xếp chúng theo thứ tự tăng dần.
Thêm một tham số: thứ tự cho truy vấn