Authority 0
Posting Rating 17
Sign in to rate this post
|
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=]<= text_field_tag :search_first_name, params[:search_first_name] %>[/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=] | <= link_to ‘Address’, @search_parts.merge({:sort => ‘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
end[/code]
- 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 objects0 != 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’
end
end
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
end
end
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
Authority 0
Posting Rating 79
Sign in to rate this post
|
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])
|