Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order and sort_by difference in Ruby on Rails ActiveRecord

I am trying to sort my data according to timestamp field in my controller, note that the timestamp field may be null and may have some value. I wrote the following query.

@item = Item.sort_by(&:item_timestamp).reverse
            .paginate(:page => params[:page], :per_page =>5)

But this gives error when I have items that have time_timestamp field value as NULL, but following query works.

@item = Item.order(:item_timestamp).reverse
            .paginate(:page => params[:page], :per_page => 5)

Can anybody tell the difference between these two queries, and in which condition to use which one?

And I am using order and reverse to get the latest items from the database, Is this the best way or there are other best ways to get the latest data from database in terms of performance?

like image 464
Dharma Avatar asked Mar 10 '17 06:03

Dharma


People also ask

What is ActiveRecord in Ruby on Rails?

Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database.

How does Sort_by work in Ruby?

sort_by works by creating what you can think of as an invisible hash. When called on an array, it calculates a set of numerical keys (known as “sort keys”), and assigns each element in the array to one of those sort keys. Then, the keys are sorted, and mapped back onto the original values.

Can you use ActiveRecord without Rails?

One of the primary aspects of ActiveRecord is that there is very little to no configuration needed. It follow convention over configuration. ActiveRecord is commonly used with the Ruby-on-Rails framework but you can use it with Sinatra or without any web framework if desired.

How do you sort a method in Ruby?

The Ruby sort method works by comparing elements of a collection using their <=> operator (more about that in a second), using the quicksort algorithm. You can also pass it an optional block if you want to do some custom sorting. The block receives two parameters for you to specify how they should be compared.


2 Answers

.sort_by is a Ruby method from Enumerable that is used to sort arrays (or array like objects). Using .sort_by will cause all the records to be loaded from the database into the servers memory, which can lead to serious performance problems (as well as your issue with nil values).

.order is a ActiveRecord method that adds a ORDER BY clause to the SQL select statement. The database will handle sorting the records. This is preferable in 99% of cases.

like image 122
max Avatar answered Sep 25 '22 01:09

max


As it was said before me, .order is quicker, and it's enough in most cases, but sometimes you need sort_by, if you want to sort by value in a relation for example.

If you have a posts table and a view_counters table, where you have the number of views by article, you can't easily sort your posts by total views with .order.

But with sort_by, you can just do:

posts = @user.posts.joins(:view_counter)
@posts = posts.sort_by { |p| p.total_views }

.sort_by going to browse each element, get the relation value, then sort by the value of this relation, just with one code line.

You can further reduce the code with &:[attributeName], for example:

@posts = posts.sort_by(&:total_views)

Also, for your last question about the reverse, you can do this:

Item.order(item_timestamp: :desc)
like image 36
escanxr Avatar answered Sep 23 '22 01:09

escanxr