Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion init.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
require 'sortable_columns'
require 'helpers/view_helpers'
require 'helpers/active_record_base_methods'

ActionController::Base.send(:include, SortableColumns)
ActionView::Base.send(:include, SortableColumns::ViewHelpers)
# allow sort_params to preserve existing params
# (minus standard params like :controller, :action, etc )
ApplicationController.send( :append_before_filter, :store_params)

ActionView::Base.send(:include, SortableColumns::ViewHelpers)
ActiveRecord::Base.send(:extend, SortableColumns::ActiveRecordBaseMethods)
10 changes: 10 additions & 0 deletions lib/helpers/active_record_base_methods.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module SortableColumns

module ActiveRecordBaseMethods
attr_accessor :sortable_methods

def sortable_instance_methods(methods)
@sortable_methods = methods.to_a
end
end
end
10 changes: 4 additions & 6 deletions lib/helpers/view_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,19 @@ module SortableColumns
module ViewHelpers

def sort_params(sortable, column)
raise ParameterError.new("Please provide a Class as your first param. Ex: sort_param(User, :created_at)") unless sortable.is_a?(Class)
raise ParameterError.new("#{sortable} has no column \"#{column}\".") unless sortable.column_names.include?(column.to_s)

SortableColumns.validate_params(sortable, :sort_by=>column)
init_session unless session[:sortable_columns]

if session[:sortable_columns][sortable.to_s.downcase.to_sym]
if session[:sortable_columns][sortable.to_s.downcase.to_sym][column.to_sym] == "asc"
return { :sort_by => column.to_s, :order => 'desc' }
return params.merge( { :sort_by => column.to_s, :order => 'desc' } )
else
return { :sort_by => column.to_s, :order => 'asc' }
return params.merge( { :sort_by => column.to_s, :order => 'asc' } )
end
end

# default
return { :sort_by => column.to_s, :order => 'desc' }
return params.merge( { :sort_by => column.to_s, :order => 'desc' } )
end

private
Expand Down
27 changes: 20 additions & 7 deletions lib/sortable_columns.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ class ParameterError < StandardError; end

def sortable_order(sortable, options = {})
if params[:sort_by] && params[:order]
validate_params(sortable)
validate_params(sortable, params)
store_sort(sortable)
return "#{params.delete(:sort_by)} #{params.delete(:order)}"
return "#{params[:sort_by]} #{params[:order]}"
else
if session[:sortable_columns] && session[:sortable_columns][sortable.to_s.downcase.to_sym]
column = session[:sortable_columns][sortable.to_s.downcase.to_sym].keys.first
Expand All @@ -17,12 +17,25 @@ def sortable_order(sortable, options = {})
end
end

private

def validate_params(sortable)
raise ParameterError.new("#{sortable} has no column \"#{params[:sort_by]}\".") unless sortable.column_names.include?(params[:sort_by])
raise ParameterError.new("Order must be \"asc\" or \"desc\"") unless params[:order] == "asc" || params[:order] == "desc"
def sortable_attributes_and_methods( sortable )
columns = sortable.column_names
columns += sortable.sortable_methods.to_a if sortable.respond_to?( :sortable_methods )
columns.map{ |c| c.to_s }
end

def validate_params(sortable, params)
raise ParameterError.new("#{sortable} has no column or sortable_method \"#{params[:sort_by]}\". \n\nIf you're trying to sort by an instance method that isn't a column name (e.g. a value from an associated table), you must define \n\n\tsortable_instance_methods :my_method_1, :my_method_2 \n\nin your model class. Don't forget to include it as a column in your query too!") unless SortableColumns.sortable_attributes_and_methods(sortable).include?(params[:sort_by].to_s)
raise ParameterError.new("Order must be \"asc\" or \"desc\" - you gave #{params[:order]}") unless params[:order].blank? || ["asc","desc"].include?(params[:order].to_s.downcase)
end


def store_params
@params = params.clone - [ :controller, :action, :authenticity_token, :page, :format, :per_page ]
end

module_function :sortable_attributes_and_methods, :validate_params

private

def store_sort(sortable)
session[:sortable_columns] ||= Hash.new
Expand Down