In Rails, Sometimes there can occur a situation like this. If there is a situation that we need to sort the data of the model using multiple columns and need not to convert in the array. Also there is already a default scope is defined. If we will use the sorting thing for the array than it will run bulk of quries and lot of time. We have to use only the Mongo Criteria.
Please understand the below mentioned examples so it will be very clear to you that how it will work.
1. If you are using desc options in the query, it is not going to work for you because there is already a default scope defined. It will work only for defined scope.
Example for 1 (Wrong):
Model :
class CommunityFeed
default_scope desc(:created_at)
end
Controller :
@cm_feeds = CommunityFeed.desc(:sticky_post).page(params[:page])
2. If you are using multiple desc options in the query, it is not going to work for you because it will work for only first desc.
Example for 2 (Wrong):
Model :
class CommunityFeed
end
Controller :
@cm_feeds = CommunityFeed.desc(:created_at).desc(:sticky_post).page(params[:page])
3. If you have defined the sorting thing in the scope than it will also not going to work for you because there is also a default scope. It will work only for one that is in the default scope.
Example for 3 (Wrong):
Model :
class CommunityFeed
default_scope desc(:created_at)
scope :desc_sticky_post, desc(:sticky_post)
end
Controller :
@cm_feeds = CommunityFeed.desc_sticky_post.page(params[:page])
4 I am sure that it will work for you. If you wants a functionality in which you have to override the default scope and need to sort using multiple columns. The unscoped is used for overriding the default scope so the query will work that is defined with unscoped. And the ordery by clause will help in sorting using multiple attributes and it maintains the mongo criteria so don’t need to worry about handling the array. I am using there a pagination and it is not giving any error for paginate for array undefined because it is in monog criteria not in array.
Using mongo criteria : ( Fast )
Example for 4 (Correct):
Model :
class CommunityFeed
default_scope desc(:created_at)
scope :desc_sticky_post, unscoped.order_by(:sticky_post => :desc, :created_at=> :desc)
end
Controller :
@cm_feeds = CommunityFeed.desc_sticky_post.page(params[:page])
The things I have discussed, it is using Mongo Criteria. If you will sort using array than it will work but it will not be efficient in the large scale of data because it will fire bulk of queries.
Same thing using array : ( It is bad practice ) => ( Very Slow )
class CommunityFeed
default_scope desc(:created_at)
def self.desc_sticky_post
self.sort_by{|p| p.sticky_post ? 0 : 1 }
end
end
Controller :
>> It will give error for paginate of array that i am using Kaminary gem
@cm_feeds = CommunityFeed.desc_sticky_post.page(params[:page])
>> It will work for array. we need to use that paginate_array attribut for array pagination.
@cm_feeds = Kaminari.paginate_array(CommunityFeed.desc_sticky_post).page(params[:page])