Module: Sortable::ClassMethods

Defined in:
lib/sortable.rb

Instance Method Summary collapse

Instance Method Details

#sortable_table(klass, options = {}) ⇒ Object

Class method to setup a controller to create a sortable table.

usage: sortable_table class_to_tabularize, optional_params

simplest example possible:

In your controller…

sortable_table User

This will create a sortable table over all your objects and display all columns. The simplest way to trim down the columns to display is to pass in a parameter specifying which columns on your object you’d like to display:

sortable_table User, :display_columns => [‘id’, ‘email’, ‘name’, ‘state’, ‘created_at’]

This will show the same sortable, searchable, paginated table with only these columns

If you need a bit more control over how the objects are fetchd and displayed this is the next simplest example:

Override the index action in your controller:

def index

get_sorted_objects(params)

end

In your index action template (within the same controller) put in a helper call to show a sortable table. You can create your own table partial to be used to display the objects. See the sortable/views/sortable/_table.html.erb (which is the default template used by the plugin) for an example.

<%= sortable_table %>

The view method will automatically generate a paginated, sortable table for the class type declared in the controller

optional_params:

:per_page - Number of records to show per page. Default is 10

The next section deals with how to change what’s displayed in the table. The first and simplest option is :display_columns. The more flexible option is to use :table_headings and :sort_map. First we’ll go over the simpler option.

:display_columns - Specifies which columns that you’d like to display in the table.

For more flexibility you can use :table_headings and :sort_map. You would most likely use this when you want to display attributes from more than one object in the same table or if you need more flexibility with regards to sort rules. :table_headings - The table heading label and sort key. Default is all the column names for the given class :sort_map - The mapping between the sort key and the table.column to sort on. Default is all the columns for the given class :include_relations - Relations to include if you choose to display a column in a related object’s table

:default_sort - The default sorting column and direction when displaying the table without any sort params. Default is ‘id DESC’

Note: You must override both :table_headings and :sort_map if you do choose to override so that the contents of the column headings match up with the contents of the sort_map they associate with. Also if you override :default_sort you’ll need to change the :table_headings and :sort_map if the new :default_sort column doesn’t currently reside within the :table_heading and :sort_map collections

Example of modifying :table_headings or :sort_map :

:table_headings => [['Name', 'name'], ['Status', 'status']]
:sort_map =>  {'name' => ['users.name'], 
               'status' => ['users.status']}

Note that both 'name' and 'status' are sort keys that map to both the table heading label and the 
database table.column combination that the heading refers to. 

Also note that :default_sort now needs to change as well since the table no longer contains the :default_sort
column of 'id':

:default_sort => ['name', 'DESC']

Example of modifying :table_headings to include a column from a related object:

:table_headings => [['Name', 'name'], ['Status', 'status'], ['Role', 'role']]
:sort_map =>  {'name' => ['users.name'], 
               'status' => ['users.status'],
               'role' => ['roles.role']}

Note that we've now added 'roles.role' to the list of columns to display and sort on. In order to
make the find work properly we also need to include the related object, so we pass in the following param:
:include_relations => [:role]

Perhaps we want to sort by role ascending by default as well. We'd pass the param value:
:default_sort => ['role', 'ASC']               

and the table is now sortable by a related object's column and is the default sort value for the table.

Search. You can specify what columns are searchable on your objects as follows:

:search_array => ['cablecar_users.username', 'cablecar_users.name']

Now search queries will only search username and name for users. By default search is enabled for all columns that are being displayed in the table. This allows you to expand or constrain those values.



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/sortable.rb', line 100

def sortable_table(klass, options={})
    @@sortable_table_options ||={}

    sort_map = HashWithIndifferentAccess.new

    if options[:table_headings] &&
       options[:sort_map]
       table_headings = options[:table_headings]
       sort_map.merge!(options[:sort_map])           
    else
      display_columns = options[:display_columns].blank? ? klass.column_names : options[:display_columns]
      table_headings = []
      klass.column_names.each do |att|
        if display_columns.include?(att)
          table_headings << [att.humanize, att]
          sort_map[att] = ["#{klass.table_name}.#{att}", 'DESC']
        end
      end           
    end

    default_sort = options[:default_sort].nil? ? ['id', 'DESC'] : options[:default_sort]
    per_page = options[:per_page].nil? ? 10 : options[:per_page]
    include_relations = options[:include_relations].nil? ? [] : options[:include_relations]        

    search_array = options[:search_array].nil? ? sort_map.values.collect {|v| v[0]} : options[:search_array]

    @@sortable_table_options[controller_name] = {:class => klass,
                                                 :table_headings => table_headings,
                                                 :default_sort => default_sort,
                                                 :sort_map => sort_map,
                                                 :search_array => search_array,
                                                 :per_page => per_page,
                                                 :include_relations => include_relations}
    
    module_eval do
      include Sortable::InstanceMethods
      def sortable_class
        @@sortable_table_options[controller_name][:class]
      end

      def sortable_table_headings
        @@sortable_table_options[controller_name][:table_headings]
      end
      
      def sortable_default_sort
        @@sortable_table_options[controller_name][:default_sort]
      end
      
      def sortable_sort_map
        @@sortable_table_options[controller_name][:sort_map]
      end
      
      def sortable_search_array
        @@sortable_table_options[controller_name][:search_array]
      end
      
      def sortable_per_page
        @@sortable_table_options[controller_name][:per_page]
      end
      
      def sortable_include_relations
        @@sortable_table_options[controller_name][:include_relations]
      end
    end
end