Dave G
Dave G

Reputation: 4386

Will_Paginate and order clause not working

I'm calling a pretty simple function, and can't seem to figure out whats going on. (I'm using rails 3.0.3 and the master branch of 'will_paginate' gem). I have the following code:

  results = Article.search(params) # returns an array of articles
  @search_results = results.paginate :page => params[:page],  :per_page=>8, :order => order_clause

No matter what I make the order_clause (for example 'article_title desc' and 'article_title asc'), the results are always the same in the same order. So when I check using something like @search_results[0], the element is always the same. In my view, they are obviously always the same as well. Am I totally missing something?

I'm sure its something silly, but I've been banging my head against the wall all night. Any help would be much appreciated!

Edited to Add: The search clause does the following:

def self.search(params)
    full_text_search(params[:query].to_s).
    category_search(params[:article_category].blank? ? '' : params[:article_category][:name]).
    payout_search(params[:payout_direction], params[:payout_value]).
    length_search(params[:length_direction], params[:length_value]).
    pending.
    distinct.
    all
  end

where each of these guys is a searchlogic based function like this:

#scopes
scope :text_search, lambda {|query|
    {
      :joins => "INNER JOIN users ON users.id IN (articles.writer_id, articles.buyer_id)",
      :conditions => ["(articles.article_title LIKE :query) OR
                       (articles.description LIKE :query) OR
                       (users.first_name LIKE :query) OR
                       (users.last_name LIKE :query)", { :query => "%#{query}%" }]
    }
  }
  scope :distinct, :select => "distinct articles.*"
#methods

    def self.payout_search(dir, val)
        return no_op if val.blank?
        send("payment_amount_#{dir.gsub(/\s+/,'').underscore}", val)
      end

      def self.length_search(dir, val)
        return no_op if val.blank?
        send("min_words_#{dir.gsub(/\s+/,'').underscore}", val)
      end

Thanks.

Upvotes: 3

Views: 3473

Answers (1)

Stephan
Stephan

Reputation: 2873

If you look at the example from the will_paginate github page you can spot one important difference between their use of the :order clause and yours:

@posts = Post.paginate :page => params[:page], :order => 'created_at DESC'

This calls paginate on the Post object (with no objects being selected yet - no SQL has been executed before paginate comes along). This is different in your example: as you state in the first line of code "returns an array of articles". The simplest I can come up with showing the problem is

  results = Model.limit(5).all
  @results = results.paginate :order => :doesnt_matter_anymore

won't sort, but this will:

  results = Model.limit(5)
  @results = results.paginate :order => :matters

It should suffice to take the all out of the search method. It makes ActiveRecord actually perform the SQL query when calling this method. Will_paginate will do that for you when you call paginate (if you let it...). Check out the section on Lazy Loading in this post about Active Record Query Interface 3.0

Upvotes: 8

Related Questions