acts_as_data_table 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/app/helpers/acts_as_data_table_helper.rb +2 -2
- data/config/locales/acts_as_data_table.en.yml +1 -0
- data/lib/acts_as_data_table.rb +1 -0
- data/lib/acts_as_data_table/scope_filters/validator.rb +1 -1
- data/lib/acts_as_data_table/sortable_columns/renderers/bootstrap3.rb +17 -0
- data/lib/acts_as_data_table/version.rb +1 -1
- metadata +5 -7
- data/lib/acts_as_data_table/session_helper.rb +0 -193
- data/lib/acts_as_data_table_helper.rb.bak +0 -165
- data/lib/named_scope_filters.rb +0 -273
@@ -147,8 +147,8 @@ module ActsAsDataTableHelper
|
|
147
147
|
if block_given?
|
148
148
|
yield sortable
|
149
149
|
else
|
150
|
-
renderer = renderer_class.
|
151
|
-
renderer.to_html
|
150
|
+
renderer = renderer_class.is_a?(Class) ? renderer_class : renderer_class.constantize
|
151
|
+
renderer.new(sortable, self).to_html
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
@@ -9,3 +9,4 @@ en:
|
|
9
9
|
general_error: "The scope filter could not be applied successfully"
|
10
10
|
invalid_date: "%{arg_name} ('%{arg_value}') is not a valid date"
|
11
11
|
invalid_record: "The filter argument '%{arg_name}' did not match any valid record in the system."
|
12
|
+
blank: "The argument '%{arg_name}' has to be given."
|
data/lib/acts_as_data_table.rb
CHANGED
@@ -16,6 +16,7 @@ require 'acts_as_data_table/scope_filters/form_helper'
|
|
16
16
|
#Sortable Column Renderers
|
17
17
|
require 'acts_as_data_table/sortable_columns/renderers/default'
|
18
18
|
require 'acts_as_data_table/sortable_columns/renderers/bootstrap2'
|
19
|
+
require 'acts_as_data_table/sortable_columns/renderers/bootstrap3'
|
19
20
|
|
20
21
|
module ActsAsDataTable
|
21
22
|
end
|
@@ -97,7 +97,7 @@ module Acts
|
|
97
97
|
elsif @model.respond_to?(proc)
|
98
98
|
result = @model.send(proc, @args)
|
99
99
|
else
|
100
|
-
raise ArgumentError.new "The method '#{
|
100
|
+
raise ArgumentError.new "The method '#{proc}' was set up as validation method for the scope '#{@scope}' in group '#{@group}' of model '#{@model.name}', but doesn't exist."
|
101
101
|
end
|
102
102
|
when NilClass
|
103
103
|
result = true
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Acts
|
2
|
+
module DataTable
|
3
|
+
module SortableColumns
|
4
|
+
module Renderers
|
5
|
+
class Bootstrap3 < Default
|
6
|
+
def direction_indicator
|
7
|
+
if @sortable.direction == 'ASC'
|
8
|
+
@action_view.content_tag(:i, nil, :class => 'glyphicon glyphicon-sort-by-attributes')
|
9
|
+
else
|
10
|
+
@action_view.content_tag(:i, nil, :class => 'glyphicon glyphicon-sort-by-attributes-alt')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_data_table
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Stefan Exner
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2015-
|
18
|
+
date: 2015-05-01 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: bundler
|
@@ -90,16 +90,14 @@ files:
|
|
90
90
|
- lib/acts_as_data_table/scope_filters/active_record.rb
|
91
91
|
- lib/acts_as_data_table/scope_filters/form_helper.rb
|
92
92
|
- lib/acts_as_data_table/scope_filters/validator.rb
|
93
|
-
- lib/acts_as_data_table/session_helper.rb
|
94
93
|
- lib/acts_as_data_table/shared/action_controller.rb
|
95
94
|
- lib/acts_as_data_table/shared/session.rb
|
96
95
|
- lib/acts_as_data_table/sortable_columns/action_controller.rb
|
97
96
|
- lib/acts_as_data_table/sortable_columns/active_record.rb
|
98
97
|
- lib/acts_as_data_table/sortable_columns/renderers/bootstrap2.rb
|
98
|
+
- lib/acts_as_data_table/sortable_columns/renderers/bootstrap3.rb
|
99
99
|
- lib/acts_as_data_table/sortable_columns/renderers/default.rb
|
100
100
|
- lib/acts_as_data_table/version.rb
|
101
|
-
- lib/acts_as_data_table_helper.rb.bak
|
102
|
-
- lib/named_scope_filters.rb
|
103
101
|
- lib/tasks/acts_as_data_table.rake
|
104
102
|
- rails/init.rb
|
105
103
|
- test/acts_as_searchable_test.rb
|
@@ -1,193 +0,0 @@
|
|
1
|
-
module Stex
|
2
|
-
module Acts
|
3
|
-
module DataTable
|
4
|
-
class SessionHelper
|
5
|
-
def initialize(session, controller_path, action, model_name)
|
6
|
-
@session = session
|
7
|
-
@controller_path = controller_path
|
8
|
-
@action = action
|
9
|
-
@model = model_name.to_s.classify.constantize
|
10
|
-
end
|
11
|
-
|
12
|
-
def controller_path
|
13
|
-
@controller_path
|
14
|
-
end
|
15
|
-
|
16
|
-
def action_name
|
17
|
-
@action
|
18
|
-
end
|
19
|
-
|
20
|
-
def model
|
21
|
-
@model
|
22
|
-
end
|
23
|
-
|
24
|
-
#----------------------------------------------------------------
|
25
|
-
# Filters
|
26
|
-
#----------------------------------------------------------------
|
27
|
-
|
28
|
-
# Adds a filter for a specific view
|
29
|
-
# If a filter for this group is already set, the new filter
|
30
|
-
# will override the existing one.
|
31
|
-
#--------------------------------------------------------------
|
32
|
-
def add_filter(group, scope, args)
|
33
|
-
controller_key = action_key(controller_path, action_name)
|
34
|
-
@session[:scope_filters] ||= {}
|
35
|
-
@session[:scope_filters][controller_key] ||= {}
|
36
|
-
|
37
|
-
args = hash_keys_to_strings(args) if args
|
38
|
-
|
39
|
-
@session[:scope_filters][controller_key][group.to_s] = {scope.to_s => args}
|
40
|
-
end
|
41
|
-
|
42
|
-
# Removes an active filter. As only one filter per group can
|
43
|
-
# be active at a time, we can simply delete the whole group.
|
44
|
-
# If all filters are deleted, we can also remove the namespaces
|
45
|
-
# in the session
|
46
|
-
#--------------------------------------------------------------
|
47
|
-
def remove_filter(group)
|
48
|
-
controller_key = action_key(controller_path, action_name)
|
49
|
-
return unless @session[:scope_filters][controller_key]
|
50
|
-
@session[:scope_filters][controller_key].delete(group.to_s)
|
51
|
-
@session[:scope_filters].delete(controller_key) if @session[:scope_filters][controller_key].empty?
|
52
|
-
@session.delete(:scope_filters) if @session[:scope_filters].empty?
|
53
|
-
end
|
54
|
-
|
55
|
-
# Removes all filters from the given controller + action
|
56
|
-
#--------------------------------------------------------------
|
57
|
-
def remove_all_filters
|
58
|
-
@session[:scope_filters].delete(action_key(controller_path, action_name))
|
59
|
-
end
|
60
|
-
|
61
|
-
# Returns all active filters for the given controller and action
|
62
|
-
#--------------------------------------------------------------
|
63
|
-
def active_filters
|
64
|
-
return {} unless @session[:scope_filters]
|
65
|
-
@session[:scope_filters][action_key(controller_path, action_name)] || {}
|
66
|
-
end
|
67
|
-
|
68
|
-
# Checks if the given filter is currently active
|
69
|
-
#--------------------------------------------------------------
|
70
|
-
def active_filter?(group, scope, args)
|
71
|
-
active = active_filters
|
72
|
-
args = hash_keys_to_strings(args) if args
|
73
|
-
|
74
|
-
active.any? &&
|
75
|
-
active[group.to_s] &&
|
76
|
-
active[group.to_s].has_key?(scope.to_s) &&
|
77
|
-
(active[group.to_s][scope.to_s].to_a - args.to_a).empty? #sometimes the session hash contains {:raise => true}, whereever it comes from...
|
78
|
-
end
|
79
|
-
|
80
|
-
#----------------------------------------------------------------
|
81
|
-
# Column Sorting
|
82
|
-
#----------------------------------------------------------------
|
83
|
-
|
84
|
-
# Replaces all current sorting columns with the new one
|
85
|
-
#--------------------------------------------------------------
|
86
|
-
def replace_sorting_column(model_name, column_name)
|
87
|
-
args = generate_sorting_arguments(model_name, column_name)
|
88
|
-
return unless args[:model].column_names.include?(column_name.to_s)
|
89
|
-
|
90
|
-
@session[:column_sorting] ||= {}
|
91
|
-
@session[:column_sorting][args[:key]] = [[args[:column], 'ASC']]
|
92
|
-
end
|
93
|
-
|
94
|
-
# Adds a new sorting column to the current controller and action
|
95
|
-
#--------------------------------------------------------------
|
96
|
-
def add_or_toggle_sorting_column(model_name, column_name)
|
97
|
-
args = generate_sorting_arguments(model_name, column_name)
|
98
|
-
|
99
|
-
return unless args[:model].column_names.include?(column_name.to_s)
|
100
|
-
|
101
|
-
@session[:column_sorting] ||= {}
|
102
|
-
@session[:column_sorting][args[:key]] ||= []
|
103
|
-
|
104
|
-
existing_entry = @session[:column_sorting][args[:key]].assoc(args[:column])
|
105
|
-
|
106
|
-
#Toggle the direction
|
107
|
-
if existing_entry
|
108
|
-
idx = @session[:column_sorting][args[:key]].index(existing_entry)
|
109
|
-
|
110
|
-
direction = existing_entry.last == 'ASC' ? 'DESC' : 'ASC'
|
111
|
-
|
112
|
-
@session[:column_sorting][args[:key]].delete(existing_entry)
|
113
|
-
|
114
|
-
@session[:column_sorting][args[:key]].insert(idx, [args[:column], direction])
|
115
|
-
else
|
116
|
-
#Simply append the new column to the sorting list
|
117
|
-
@session[:column_sorting][args[:key]] << [args[:column], 'ASC']
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
# Removes a sorting column from current controller and action
|
122
|
-
#--------------------------------------------------------------
|
123
|
-
def remove_sorting_column(model_name, column_name)
|
124
|
-
args = generate_sorting_arguments(model_name, column_name)
|
125
|
-
return if @session[:column_sorting].nil? || @session[:column_sorting].empty?
|
126
|
-
return unless @session[:column_sorting].has_key?(args[:key])
|
127
|
-
|
128
|
-
existing_entry = @session[:column_sorting][args[:key]].assoc(args[:column])
|
129
|
-
@session[:column_sorting][args[:key]].delete(existing_entry) if existing_entry
|
130
|
-
|
131
|
-
#Remove the controller namespace from the session if it's empty
|
132
|
-
@session[:column_sorting].delete(args[:key]) if @session[:column_sorting][args[:key]].empty?
|
133
|
-
end
|
134
|
-
|
135
|
-
# Returns all sorting columns as a string
|
136
|
-
#--------------------------------------------------------------
|
137
|
-
def sorting_columns_string
|
138
|
-
controller_key = action_key(controller_path, action_name)
|
139
|
-
return nil if @session[:column_sorting].nil? || @session[:column_sorting].empty?
|
140
|
-
return nil unless @session[:column_sorting].has_key?(controller_key)
|
141
|
-
|
142
|
-
@session[:column_sorting][controller_key].map {|column_and_direction| column_and_direction.join(' ')}.join(', ')
|
143
|
-
end
|
144
|
-
|
145
|
-
# Returns the current sorting direction for a given column
|
146
|
-
# or nil if this column is currently not active.
|
147
|
-
#--------------------------------------------------------------
|
148
|
-
def sorting_direction(model_name, column_name)
|
149
|
-
args = generate_sorting_arguments(model_name, column_name)
|
150
|
-
|
151
|
-
return nil if @session[:column_sorting].nil? || @session[:column_sorting].empty?
|
152
|
-
return nil unless @session[:column_sorting].has_key?(args[:key])
|
153
|
-
entry = @session[:column_sorting][args[:key]].assoc(args[:column])
|
154
|
-
entry ? entry.last : nil
|
155
|
-
end
|
156
|
-
|
157
|
-
# loads the sorting defaults for the current action
|
158
|
-
# Parameters==
|
159
|
-
# defaults:: [['users.last_name', 'ASC'], ['users.first_name', 'ASC']]
|
160
|
-
#--------------------------------------------------------------
|
161
|
-
def load_sorting_defaults(defaults = [])
|
162
|
-
return if defaults.empty?
|
163
|
-
controller_key = action_key(controller_path, action_name)
|
164
|
-
@session[:column_sorting] = {}
|
165
|
-
@session[:column_sorting][controller_key] = defaults
|
166
|
-
end
|
167
|
-
|
168
|
-
private
|
169
|
-
|
170
|
-
def generate_sorting_arguments(model_name, column_name)
|
171
|
-
model = model_name.to_s.classify.constantize
|
172
|
-
{
|
173
|
-
:model => model,
|
174
|
-
:key => action_key(controller_path, action_name),
|
175
|
-
:column => "#{model.table_name}.#{column_name}"
|
176
|
-
}
|
177
|
-
end
|
178
|
-
|
179
|
-
def action_key(controller, action)
|
180
|
-
[controller.gsub("/", "_"), action].join('_')
|
181
|
-
end
|
182
|
-
|
183
|
-
def hash_keys_to_strings(hash)
|
184
|
-
new_hash = {}
|
185
|
-
hash.each do |key, value|
|
186
|
-
new_hash[key.to_s] = value
|
187
|
-
end
|
188
|
-
new_hash
|
189
|
-
end
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
@@ -1,165 +0,0 @@
|
|
1
|
-
module ActsAsDataTableHelper
|
2
|
-
|
3
|
-
def scope_filter_link(group, filter, options = {})
|
4
|
-
|
5
|
-
end
|
6
|
-
#
|
7
|
-
# #----------------------------------------------------------------
|
8
|
-
# # Filters
|
9
|
-
# #----------------------------------------------------------------
|
10
|
-
#
|
11
|
-
# # Generates a link to to add or remove a certain filter to the
|
12
|
-
# # current controller/action.
|
13
|
-
# # Parameters:
|
14
|
-
# # +group+:: The group name the filter belongs to
|
15
|
-
# #
|
16
|
-
# # ===Options
|
17
|
-
# # +:filter+:: The filter name to be applied
|
18
|
-
# # +:caption+:: The link caption, defaults to a localization
|
19
|
-
# # +:remove+:: If set to +true+, the filter will be removed instead of (re-)added
|
20
|
-
# # +:args+:: Args to be used when applying the filter
|
21
|
-
# # +:auto_remove+:: If set to true, a click on an active filter will remove it again.
|
22
|
-
# #
|
23
|
-
# # All other options will be used as html_options for the resulting link
|
24
|
-
# #--------------------------------------------------------------
|
25
|
-
# def scope_filter_link(group, options = {})
|
26
|
-
# filter_name = options.delete(:filter)
|
27
|
-
# caption = options.delete(:caption) || t("activerecord.scopes.#{searchable_session.model.table_name}.#{filter_name}")
|
28
|
-
# args = options.delete(:args)
|
29
|
-
# surrounding_tag = options.delete(:surrounding)
|
30
|
-
# auto_remove = options.delete(:auto_remove) && searchable_session.active_filter?(group, filter_name, args)
|
31
|
-
# remove = options.delete(:remove)
|
32
|
-
#
|
33
|
-
# if remove || auto_remove
|
34
|
-
# url = {:scope_filters => {:remove => group}}
|
35
|
-
# else
|
36
|
-
# url = {:scope_filters => {:group => group, :name => filter_name, :args => args}}
|
37
|
-
# end
|
38
|
-
#
|
39
|
-
# classes = options[:class].try(:split, ' ') || []
|
40
|
-
# classes << 'active' if searchable_session.active_filter?(group, filter_name, args)
|
41
|
-
# options[:class] = classes.join(' ')
|
42
|
-
# link = link_to_remote caption, :url => url, :method => :get, :html => options
|
43
|
-
# surrounding_tag ? content_tag(surrounding_tag, link, :class => options[:class]) : link
|
44
|
-
# end
|
45
|
-
#
|
46
|
-
# # Generates the URL to remove all filters from the current action
|
47
|
-
# #--------------------------------------------------------------
|
48
|
-
# def remove_all_scope_filters_url
|
49
|
-
# {:scope_filters => {:remove_all => true}}
|
50
|
-
# end
|
51
|
-
#
|
52
|
-
# # Generates the URL to be used as form action to add a new filter
|
53
|
-
# #--------------------------------------------------------------
|
54
|
-
# def scope_filter_form_url(group, filter_name)
|
55
|
-
# {:scope_filters => {:group => group, :name => filter_name}}
|
56
|
-
# end
|
57
|
-
#
|
58
|
-
# # Generates the form element name for filter args inside
|
59
|
-
# # a form
|
60
|
-
# #--------------------------------------------------------------
|
61
|
-
# def scope_filter_field_name(arg_name)
|
62
|
-
# "scope_filters[args][#{arg_name}]"
|
63
|
-
# end
|
64
|
-
#
|
65
|
-
# # Generates a form field id for the given scope and arg
|
66
|
-
# #--------------------------------------------------------------
|
67
|
-
# def scope_filter_field_id(scope, arg_name)
|
68
|
-
# [scope, arg_name].join('_')
|
69
|
-
# end
|
70
|
-
#
|
71
|
-
# # Builds the caption for an active filter
|
72
|
-
# #--------------------------------------------------------------
|
73
|
-
# def scope_filter_caption(active_filter)
|
74
|
-
# searchable_session.model.scope_caption(active_filter[:filter], active_filter[:args])
|
75
|
-
# end
|
76
|
-
#
|
77
|
-
# # Returns the arguments for a currently active filter or nil
|
78
|
-
# # if the given filter is currently not active.
|
79
|
-
# #-------------------------------------------------------------
|
80
|
-
# def scope_filter_arg(filter_name, arg_name)
|
81
|
-
# @filter_args ||= {}
|
82
|
-
# @filter_args[filter_name.to_s] ||= {}
|
83
|
-
#
|
84
|
-
# unless @filter_args[filter_name.to_s].has_key? arg_name.to_s
|
85
|
-
# filter = active_scope_filters.select{|f| f[:filter].to_s == filter_name.to_s}.first
|
86
|
-
# if filter
|
87
|
-
# @filter_args[filter_name.to_s] = filter[:args]
|
88
|
-
# else
|
89
|
-
# #If the filter is currently not active, cache the argument anyway with nil
|
90
|
-
# @filter_args[filter_name.to_s] ||= {}
|
91
|
-
# @filter_args[filter_name.to_s][arg_name.to_s] = nil
|
92
|
-
# end
|
93
|
-
# end
|
94
|
-
#
|
95
|
-
# @filter_args[filter_name.to_s][arg_name.to_s]
|
96
|
-
# end
|
97
|
-
#
|
98
|
-
# # Returns all active filters in a format which is easier to
|
99
|
-
# # process than the original hash structure. Each element of the
|
100
|
-
# # returned array contains the following properties:
|
101
|
-
# #
|
102
|
-
# # +:delete_url+:: A url hash which contains the necessary parameters to
|
103
|
-
# # remove the current filter from the active list
|
104
|
-
# #
|
105
|
-
# # +:group+:: The filter group this filter is in (in case you want to
|
106
|
-
# # user the +filter_link+ helper method)
|
107
|
-
# #
|
108
|
-
# # +:filter+:: The filter name
|
109
|
-
# #
|
110
|
-
# # +:args+:: The arguments the filter was applied to (for display reasons)
|
111
|
-
# #--------------------------------------------------------------
|
112
|
-
# def active_scope_filters
|
113
|
-
# return @active_filters if @active_filters
|
114
|
-
#
|
115
|
-
# @active_filters = []
|
116
|
-
# searchable_session.active_filters.each do |group, filters|
|
117
|
-
# filters.each do |filter, args|
|
118
|
-
# @active_filters << {:delete_url => {:scope_filters => {:remove => group}},
|
119
|
-
# :group => group,
|
120
|
-
# :filter => filter,
|
121
|
-
# :args => HashWithIndifferentAccess.new(args)}
|
122
|
-
# end
|
123
|
-
# end
|
124
|
-
# @active_filters
|
125
|
-
# end
|
126
|
-
#
|
127
|
-
# # Returns the active scope filter for a given filter group
|
128
|
-
# # If you hand in a block, the filter will be available inside
|
129
|
-
# # If there is no active filter for the given group,
|
130
|
-
# # the block is not executed.
|
131
|
-
# #--------------------------------------------------------------
|
132
|
-
# def active_scope_filter(group, &proc)
|
133
|
-
# filter = active_scope_filters.select {|sf| sf[:group].to_s == group.to_s}.first
|
134
|
-
# if block_given?
|
135
|
-
# yield filter if filter
|
136
|
-
# else
|
137
|
-
# filter
|
138
|
-
# end
|
139
|
-
# end
|
140
|
-
#
|
141
|
-
# #----------------------------------------------------------------
|
142
|
-
# # Sorting Columns
|
143
|
-
# #----------------------------------------------------------------
|
144
|
-
#
|
145
|
-
# def sortable_column(model_name, column_name, caption = nil, &proc)
|
146
|
-
# sortable = Struct.new(:caption, :direction, :active, :url_replace, :url_add_toggle, :url_remove).new
|
147
|
-
#
|
148
|
-
# sortable.direction = searchable_session.sorting_direction(model_name, column_name)
|
149
|
-
# sortable.active = sortable.direction.present?
|
150
|
-
#
|
151
|
-
# sortable.url_replace = {:sorting_columns => {:replace => true, :model_name => model_name, :column_name => column_name}}
|
152
|
-
# sortable.url_add_toggle = {:sorting_columns => {:add => true, :model_name => model_name, :column_name => column_name}}
|
153
|
-
# sortable.url_remove = {:sorting_columns => {:remove => true, :model_name => model_name, :column_name => column_name}}
|
154
|
-
# sortable.caption = caption
|
155
|
-
#
|
156
|
-
#
|
157
|
-
# #If a block is given, we let the user handle the content of the table
|
158
|
-
# #header himself. Otherwise, we'll generate the default links.
|
159
|
-
# if block_given?
|
160
|
-
# yield sortable
|
161
|
-
# else
|
162
|
-
# render :partial => 'shared/sortable_column', :object => sortable
|
163
|
-
# end
|
164
|
-
# end
|
165
|
-
end
|
data/lib/named_scope_filters.rb
DELETED
@@ -1,273 +0,0 @@
|
|
1
|
-
module Stex
|
2
|
-
module Acts
|
3
|
-
module DataTable
|
4
|
-
module NamedScopeFilters
|
5
|
-
module ActiveRecord
|
6
|
-
def self.included(base)
|
7
|
-
base.send :extend, ClassMethods
|
8
|
-
end
|
9
|
-
|
10
|
-
module ClassMethods
|
11
|
-
# Generates methods to automatically combine named scopes
|
12
|
-
# based on the given input
|
13
|
-
# Arguments are all named scopes you'd like to include into
|
14
|
-
# The parameter includes all filters which may be used by the automatic
|
15
|
-
# data filtering later.
|
16
|
-
# {:group_name => [scope1, scope2, [scope_with_arguments, arg1, arg2], scope4]}
|
17
|
-
#--------------------------------------------------------------
|
18
|
-
def has_named_scope_filters(filter_groups = {})
|
19
|
-
if filter_groups.empty? #No groups given, no filters created
|
20
|
-
throw 'is_named_scope_filterable needs arguments to run.'
|
21
|
-
end
|
22
|
-
|
23
|
-
#Convert filters
|
24
|
-
filter_groups.each do |group_name, filters|
|
25
|
-
filters = Array(filters)
|
26
|
-
filters.map! {|f| Array(f)}
|
27
|
-
|
28
|
-
#Check if all given named scopes actually exist
|
29
|
-
filters.each do |ns|
|
30
|
-
scope_name = ns.first
|
31
|
-
logger.warn "The scope '#{scope_name}' in group '#{group_name}' does not exist." unless scopes.has_key?(scope_name)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
#Create a method to test if a given filter is valid
|
36
|
-
define_singleton_method 'named_scope_filter?' do |group, name, args|
|
37
|
-
filter_groups[group] && filter_groups[group].assoc(name).present?
|
38
|
-
end
|
39
|
-
|
40
|
-
#Generate a method to actually apply the various filters to the current
|
41
|
-
#model.
|
42
|
-
define_singleton_method(:apply_scope_filters) do |scope_filter_groups|
|
43
|
-
result = self
|
44
|
-
scope_filter_groups.each do |group_name, scope_filters|
|
45
|
-
set_scopes = filter_groups[group_name.to_sym]
|
46
|
-
scope_filters.each do |filter, args|
|
47
|
-
set_filter = set_scopes.assoc(filter.to_sym)
|
48
|
-
arg_names = set_filter.drop(1)
|
49
|
-
scope_args = arg_names.map {|a| args[a.to_s]}
|
50
|
-
result = result.send(set_filter.first, *scope_args)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
result
|
54
|
-
end
|
55
|
-
|
56
|
-
#Generate a method to label applied filters.
|
57
|
-
#This method only does default labelling and will most likely be
|
58
|
-
#overridden in the actual model
|
59
|
-
define_singleton_method(:scope_caption) do |scope_name, args|
|
60
|
-
options = {:scope => "activerecord.scopes.#{table_name}", :default => scope_name}
|
61
|
-
symbol_args = {}
|
62
|
-
args.each do |k,v|
|
63
|
-
symbol_args[k.to_sym] = v
|
64
|
-
end
|
65
|
-
I18n.t(scope_name, options.merge(symbol_args))
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
#def is_named_scope_sortable(*args)
|
70
|
-
# options = args.pop if args.last.is_a?(Hash)
|
71
|
-
# processed_args = args.map {|a| generate_sortable_columns_and_includes(a)}.flatten
|
72
|
-
#
|
73
|
-
# column_names = []
|
74
|
-
# unfiltered_includes = []
|
75
|
-
#
|
76
|
-
# processed_args.each do |arg|
|
77
|
-
# column_names += arg[:columns]
|
78
|
-
# unfiltered_includes += arg[:includes]
|
79
|
-
# end
|
80
|
-
#
|
81
|
-
# #TODO: filter longer include chains, have to get a real example first.
|
82
|
-
#
|
83
|
-
#
|
84
|
-
# 1
|
85
|
-
#end
|
86
|
-
|
87
|
-
|
88
|
-
## Processes arguments for the sortable generator
|
89
|
-
## Returns column names and necessary includes
|
90
|
-
##--------------------------------------------------------------
|
91
|
-
#def generate_sortable_columns_and_includes(arg, model = self)
|
92
|
-
# columns = []
|
93
|
-
# includes = []
|
94
|
-
# #Associations from the current model
|
95
|
-
# if arg.is_a?(Hash)
|
96
|
-
# arg.each do |association_name, columns_and_associations|
|
97
|
-
# association_endpoint = Stex::Acts::Searchable::DataHolder.graph.associations_for(model)[association_name.to_s]
|
98
|
-
# Array(columns_and_associations).each do |new_arg|
|
99
|
-
# processed_arg = generate_sortable_columns_and_includes(new_arg, association_endpoint)
|
100
|
-
# columns += processed_arg[:columns]
|
101
|
-
# if processed_arg[:includes].any?
|
102
|
-
# includes << {association_name => processed_arg[:includes]}
|
103
|
-
# else
|
104
|
-
# includes << association_name if processed_arg[:columns].any?
|
105
|
-
# end
|
106
|
-
# end
|
107
|
-
# end
|
108
|
-
# else
|
109
|
-
# columns << "#{model.table_name}.#{arg}" if model.column_names.include?(arg.to_s)
|
110
|
-
# end
|
111
|
-
#
|
112
|
-
# {:columns => columns, :includes => includes}
|
113
|
-
#end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
module ActionController
|
118
|
-
def self.included(base)
|
119
|
-
base.send :extend, ClassMethods
|
120
|
-
end
|
121
|
-
|
122
|
-
module ClassMethods
|
123
|
-
# Generates the necessary controller methods to add and remove filters
|
124
|
-
# Expects the model name and a list of methods the filters will be used for
|
125
|
-
# Important: Do not use the model constant (e.g. User), it might break
|
126
|
-
# your database setup.
|
127
|
-
#
|
128
|
-
# == Examples
|
129
|
-
# scope_filters :user, :index
|
130
|
-
#--------------------------------------------------------------
|
131
|
-
def scope_filters(model_name, *args)
|
132
|
-
helper_method :searchable_session
|
133
|
-
|
134
|
-
before_filter :add_scope_filter, :only => args
|
135
|
-
before_filter :remove_scope_filter, :only => args
|
136
|
-
before_filter :remove_all_scope_filters, :only => args
|
137
|
-
before_filter :load_active_scope_filters, :only => args
|
138
|
-
|
139
|
-
helper :acts_as_data_table
|
140
|
-
|
141
|
-
# Adds a filter to the current data table. Works with the
|
142
|
-
# named scope filterable plugin.
|
143
|
-
# Expects the following params to be set:
|
144
|
-
# :scope_filters =>
|
145
|
-
# :group -- The group the named scope belongs to
|
146
|
-
# :name -- The named scope name inside the group
|
147
|
-
# :args -- Array of arguments to be passed to the named scope
|
148
|
-
# If any of these params (except filter_args which is optional)
|
149
|
-
# is not set, the filter will not be added.
|
150
|
-
#--------------------------------------------------------------
|
151
|
-
define_method(:add_scope_filter) do
|
152
|
-
return if params[:scope_filters].blank?
|
153
|
-
return if [:group, :name].any? { |p| params[:scope_filters][p].blank? }
|
154
|
-
|
155
|
-
group = params[:scope_filters][:group].to_sym
|
156
|
-
name = params[:scope_filters][:name].to_sym
|
157
|
-
args = params[:scope_filters][:args]
|
158
|
-
args = nil if args.blank? #No empty string here
|
159
|
-
|
160
|
-
model = model_name.to_s.classify.constantize
|
161
|
-
|
162
|
-
#If the given filter is not valid, do not add it to the filters list
|
163
|
-
return unless model.named_scope_filter?(group, name, args)
|
164
|
-
searchable_session.add_filter(group, name, args)
|
165
|
-
end
|
166
|
-
|
167
|
-
# Removes a filter from the current data table.
|
168
|
-
# Expects the following params to be set:
|
169
|
-
# :scope_filters =>
|
170
|
-
# :group -- The group the named scope belongs to
|
171
|
-
# :remove => true
|
172
|
-
#--------------------------------------------------------------
|
173
|
-
define_method(:remove_scope_filter) do
|
174
|
-
return if params[:scope_filters].blank?
|
175
|
-
return if params[:scope_filters][:remove].blank?
|
176
|
-
searchable_session.remove_filter(params[:scope_filters][:remove])
|
177
|
-
end
|
178
|
-
|
179
|
-
# Removes all filters from the current controller and action
|
180
|
-
#--------------------------------------------------------------
|
181
|
-
define_method(:remove_all_scope_filters) do
|
182
|
-
return if params[:scope_filters].blank?
|
183
|
-
return if params[:scope_filters][:remove_all].blank?
|
184
|
-
searchable_session.remove_all_filters
|
185
|
-
end
|
186
|
-
|
187
|
-
# Session Helper instance accessor
|
188
|
-
#--------------------------------------------------------------
|
189
|
-
define_method(:searchable_session) do
|
190
|
-
@searchable_session = Stex::Acts::DataTable::SessionHelper.new(session, controller_path, action_name, model_name)
|
191
|
-
end
|
192
|
-
|
193
|
-
# Loads the active filters into an instance variable, just in case
|
194
|
-
# that naming changes later
|
195
|
-
#--------------------------------------------------------------
|
196
|
-
define_method(:load_active_scope_filters) do
|
197
|
-
@loaded_scope_filters = searchable_session.active_filters
|
198
|
-
end
|
199
|
-
|
200
|
-
#Make the helper methods private so rails does not handle them as actions
|
201
|
-
private :add_scope_filter, :remove_scope_filter, :searchable_session, :load_active_scope_filters
|
202
|
-
end
|
203
|
-
|
204
|
-
# Adds methods for automatic column sorting to the controller
|
205
|
-
# Parameters:
|
206
|
-
# actions_and_defaults:: Hash of actions which will be used to
|
207
|
-
# display sortable content and their initial sorting
|
208
|
-
# columns.
|
209
|
-
#
|
210
|
-
# == Example
|
211
|
-
# column_sorting :index => [['users.last_name', 'ASC'], ['users.first_name', 'ASC']]
|
212
|
-
#--------------------------------------------------------------
|
213
|
-
def column_sorting(actions_and_defaults = {})
|
214
|
-
|
215
|
-
before_filter :add_or_toggle_sorting_column, :only => actions_and_defaults.keys
|
216
|
-
before_filter :replace_sorting_column, :only => actions_and_defaults.keys
|
217
|
-
before_filter :remove_sorting_column, :only => actions_and_defaults.keys
|
218
|
-
before_filter :load_sorting_columns, :only => actions_and_defaults.keys
|
219
|
-
|
220
|
-
param_namespace = :sorting_columns
|
221
|
-
|
222
|
-
# Adds a sorting column to the current sorting columns or
|
223
|
-
# toggles its direction if it is already part of the
|
224
|
-
# active sorting.
|
225
|
-
#
|
226
|
-
# Parameters
|
227
|
-
# :sorting_columns => {
|
228
|
-
# :model_name => 'sale',
|
229
|
-
# :column_name => 'reference'
|
230
|
-
# }
|
231
|
-
#--------------------------------------------------------------
|
232
|
-
define_method(:add_or_toggle_sorting_column) do
|
233
|
-
return if params[param_namespace].blank?
|
234
|
-
return if [:add, :model_name, :column_name].select {|p| params[param_namespace][p].blank?}.any?
|
235
|
-
searchable_session.add_or_toggle_sorting_column(params[param_namespace][:model_name], params[param_namespace][:column_name])
|
236
|
-
end
|
237
|
-
|
238
|
-
# Replaces all current sorting columsn with the given one
|
239
|
-
#--------------------------------------------------------------
|
240
|
-
define_method(:replace_sorting_column) do
|
241
|
-
return if params[param_namespace].blank?
|
242
|
-
return if [:replace, :model_name, :column_name].select {|p| params[param_namespace][p].blank?}.any?
|
243
|
-
searchable_session.replace_sorting_column(params[param_namespace][:model_name], params[param_namespace][:column_name])
|
244
|
-
end
|
245
|
-
|
246
|
-
# Removes a column from the current sorting columns
|
247
|
-
#--------------------------------------------------------------
|
248
|
-
define_method(:remove_sorting_column) do
|
249
|
-
return if params[param_namespace].blank?
|
250
|
-
return if [:remove, :model_name, :column_name].select {|p| params[param_namespace][p].blank?}.any?
|
251
|
-
searchable_session.remove_sorting_column(params[param_namespace][:model_name], params[param_namespace][:column_name])
|
252
|
-
end
|
253
|
-
|
254
|
-
# Loads the current sorting string into an instance variable
|
255
|
-
#--------------------------------------------------------------
|
256
|
-
define_method(:load_sorting_columns) do
|
257
|
-
@current_sorting_string = searchable_session.sorting_columns_string
|
258
|
-
|
259
|
-
#If there is no user-set sorting, load the default sorting into the session.
|
260
|
-
if @current_sorting_string.blank?
|
261
|
-
searchable_session.load_sorting_defaults(actions_and_defaults[action_name.to_sym])
|
262
|
-
end
|
263
|
-
|
264
|
-
@current_sorting_string = searchable_session.sorting_columns_string
|
265
|
-
end
|
266
|
-
|
267
|
-
end
|
268
|
-
end
|
269
|
-
end
|
270
|
-
end
|
271
|
-
end
|
272
|
-
end
|
273
|
-
end
|