Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added some features to sortable_columns #1

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
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