am-rails
am-rails

Reputation: 1473

How do I order database records in rails by most recent?

I want to order all the items in a model Item so it displays the most recent ones first. According to the Rails guide, the following code should work:

 Item.order("created_at DESC")

However, when I type that (or varieties) in the terminal, the most recent item always shows up last, and that's how they show up on my page. How do I efficiently retrieve them with he most recent first? (I'm going to display only some of them at a time on each page.)

Note that my default scope for items is oldest first.

Update: This is the SQL I get:

SELECT "comments".* FROM "comments" ORDER BY comments.created_at ASC, created_at DESC

So I guess I shouldn't use default scopes...

Upvotes: 14

Views: 14249

Answers (6)

Dinesh Vaitage
Dinesh Vaitage

Reputation: 3183

Correct one and tested

@purchase_orders = current_company.purchase_orders.order(:date)
@purchase_orders = @purchase_orders.reverse_order 

Upvotes: 0

qqbenq
qqbenq

Reputation: 10460

I realise this is a really old question, but none of the answers contain the solution without writing raw SQL, which is available since Rails 3+:

Item.order(created_at: :desc)

or using the reverse_order method:

Item.order(:created_at).reverse_order

See more at http://guides.rubyonrails.org/active_record_querying.html#ordering and http://guides.rubyonrails.org/active_record_querying.html#reverse-order.

Upvotes: 13

junil
junil

Reputation: 768

Item.unscoped.order('created_at DESC') should work.Using reverse might decrease the performance when the number of records increases

Upvotes: 1

Simone Carletti
Simone Carletti

Reputation: 176392

The query you posted is correct

Item.order("created_at DESC")

The only reason why it would not work is if there is anything else conflicting with it. In general, the conflict is represented by a default_scope.

If you have a default scope that overrides your order, you should first unscope the query

Item.unscoped { Item.order("created_at DESC") } 

If you are using default scopes, I strongly encourage you to avoid them. They are very hard to debug and unscope.

There are very few cases where default scopes make sense. You can simply pass the (default) scope at select time in the controller or create a custom method for it.

Upvotes: 14

am-rails
am-rails

Reputation: 1473

I modified CDub's answer with reverse so it now works:

 Item.order(:created_at).reverse

I'm still not sure why the Rails guide's way doesn't work. Also the above method doesn't work well with pagination.

Upvotes: 3

Nitin Jain
Nitin Jain

Reputation: 3083

you can add You can also define the default order in Item model

default_scope order('created_at DESC') 

Upvotes: -1

Related Questions