Welcome to Working With Rails


Discussion Forums

Discuss all things Ruby on Rails with perhaps the web's most vibrant group of Ruby on Rails enthusiasts.
Input On My Will_paginate ext.
2 Posts
Input On My Will_paginate ext.

I'm posting this for review and suggestions, and for people that need some basic sorting and searching added to their will_paginate generated collections. Please feel free to (productively) criticize the code snippets below.

Search fields need to have the name "search" plus the column name or "search_other_table_dot" for another table ( 'other_table' ) being joined the the main table. VIEW: [code=][/code] In order to sort the found results, use the following links as column headings. :sort will specify which column to sort by, and :order (either a or d) will define whether to sort in ASC or DESC order. @search_parts will keep track of the search parameter, so they won't get lost. VIEW: [code=] 'customers.address_line_1', :order => @order}) -%>[/code] Here is the controller part."ManuPaginate" takes the params (POST or GET submitted data) which includes search terms and column sorting info, and an array of classes that are involved with the main class/table first. ( i.e. Customer has_many Orders). The second line oscillates between increasing or decreasing column order, which allows for one link to be used for sorting the column both ways.

CONTROLLER [code=]@customers, @search_parts = ManuPaginate.search(params, [Customer, Order]) @order = params[:order] == 'd' ? 'a' : 'd'[/code] My Addition to Will_Paginate [code=] def self.search(parts, objects)

raise "No objects specified for searching or sorting." if objects.empty?

includes = Array.new # For left joining / including other tables / classes
valid_columns = Array.new # For validating column names
search_parameters = Hash.new # Parameters variables for searches
column_order = nil # column name plus sorting direction

# Create an array of all valid columns (table.column)
objects.map {|object| 
object.column_names.map{|column| valid_columns << object.table_name + '.' + column}
includes << object.name.downcase if objects[0] != object

# Set sorting information (column name [+ DESC])
if valid_columns.include?(parts[:sort])
 column_order = parts[:sort]
  search_parameters[:sort] = column_order
  if parts[:order] == 'd' # The default sorting order is ASC so only add DESC if it is explicitly requested
    column_order += ' DESC'
    search_parameters[:order] = 'd'

search_conditions = ['']
search_fields = Array.new
parts.each do | key, value |
  column = key.sub 'search_','' # String search_ from search parameters
  column = column.sub '_dot_','.' # for searches in tables other than it's own
  column = objects[0].table_name + '.' + column unless column.include? '.'
  if not value.empty? and valid_columns.include?(column)
    search_fields << column + ' LIKE ?'
    search_conditions << "%" + value.gsub(' ','%') + "%"
    search_parameters[key] = value
search_conditions[0] = search_fields.join ' AND ' # Create condition sql code

table_collection = objects[0].paginate :per_page => 15, :page => parts[:page], :include => includes, :order => column_order , :conditions => search_conditions

return table_collection, search_parameters


Wow... the forum did a number on that post..

I think I follow much of it though, but whats the reason for moving the conditions and ordering to the paginate plugin? Seems that doesn't have anything to do with paginating.

I always end up using something like..

@groups = Group.paginate_public(:all, :conditions => [conditions.join(" AND "), bind_variables], :include => cond_include, :order => order, :page => params[:page], :per_page => params[:per_page])

2 Posts
Login to add your message