Look at this railscasts #228 http://railscasts.com/episodes/228-sortable-table-columns
def sortable(column, title = nil)
title ||= column.titleize
css_class = column == sort_column ? "current #{sort_direction}" : nil
direction = column == sort_column && sort_direction == "asc" ? "desc" : "asc"
link_to title, {:sort => column, :direction => direction}, {:class => css_class}
end
When you have functional sort columns, you then will need to save it to the db
A basic table with: user_id, page_name (or table_name), sort_column, sort_direction
Then when the user loads a page you would check against the saved settings and load them if they exist, if they don't you can load a default.
This is the idea, I do not have time to write the code for it, but it should be fairly straight forward.
Update:
Since I had to do this at work, I will post my code.
The railscast above implements the following three functions, which allow for sorting on a column.
application_controller.rb/or specific_controller.rb
def sort_column
Product.column_names.include?(params[:sort]) ? params[:sort] : "name"
end
def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
end
And the controller that uses it
def index
@products = Product.order(sort_column + " " + sort_direction)
end
Now, in order to remember what the user selected for the sort and to use that instead of always loading the default sortable column we need to create a table for the user_preferences
create a migration for the preference table like
create_table :user_preferences do |t|
t.string :action
t.string :preference
t.references :user
end
add_index :user_preferences, :user_id
When we search now (path -> 'specific_controller#index?direction=asc&sort=name') we need to save/update the user's preference
def index
preference = UserPreference.find_by_user_id_and_action(User.current_user.id, params[:action])
#Save/update preference based on column sort
if params[:sort]
unless preference.nil?
preference.update_attribute(:preference, "#{params[:sort]},#{params[:direction]}")
else
preference = UserPreference.new(:user => User.current_user, :preference => "#{params[:sort]},#{params[:direction]}", :action => params[:action])
end
end
populate_table_based_on_preference(preference)
end
def populate_table_based_on_preference(preference)
unless preference.nil?
@products = Product.order(preference.preference.split(',')[0]+ " " + preference.preference.split(',')[1])
else
@products = Product.order(sort_column + " " + sort_direction)
end
end
Then we need to update our methods (sort_column/direction -> What column are we sorting/ Which direction? )
def sort_column
#What are we sorting on?
preference = UserPreference.find_by_user_id_and_action(User.current_user.id, params[:action])
unless preference.nil?
preference.preference.split(',')[0]
else
Product.column_names.include?(params[:sort]) ? params[:sort] : "name"
end
end
def sort_direction
preference = UserPreference.find_by_user_id_and_action(User.current_user.id, params[:action])
#what is the search direction
unless preference.nil?
preference.preference.split(',')[1]
else
%w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
end
end