Overriding the default scope and sorting using multiple columns in rails ( No use of Array ), Mongo DB

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])

About the author

Being the CEO and Founder of ClecoTech International, Mr. Ashish Prajapati is dedicated towards his aim of mentoring young startups into a full-fledged businesses. He is helping startups from America, Europe, India, and various other countries through proper guidance and the use of latest technologies to develop their innovation and ideas into definite realities.

Leave a Reply

Your email address will not be published. Required fields are marked *