Reputation: 30284
I'm designing a table on view. For instance, they have two columns are ID
and name
. When a user clicks to the ID
column, I want the data will be sorted by ID
. Similarly, if a user clicks name
column, the data
will be sorted by name
.
My question is :
Is there any way to put this into the model (database model), hence, when user click one column, its status will be saved and the database will look at this to return record according to this status.
if not, how I put this code in view.
Please help me.
Thanks :)
Upvotes: 1
Views: 5254
Reputation: 14943
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
Upvotes: 3