active-record-data-tables 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/VERSION +1 -1
- data/active-record-data-tables.gemspec +2 -2
- data/lib/active-record-data-tables.rb +42 -31
- metadata +30 -30
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "active-record-data-tables"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["kaspernj"]
|
12
|
-
s.date = "2013-
|
12
|
+
s.date = "2013-07-09"
|
13
13
|
s.description = "Helping functionality for filtering, sorting and stuff like that with data-tables and ActiveRecord."
|
14
14
|
s.email = "k@spernj.org"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -8,36 +8,36 @@ class ActiveRecordDataTables
|
|
8
8
|
@force_filter_for = @args[:force_filter_for]
|
9
9
|
@dts = @params[:dataTables]
|
10
10
|
@columns = @args[:columns]
|
11
|
-
|
11
|
+
|
12
12
|
@model = @args[:model]
|
13
13
|
raise "No ':model' was given." unless @model
|
14
14
|
@model_method_name = StringCases.camel_to_snake(@model.name)
|
15
|
-
|
15
|
+
|
16
16
|
@joins = {}
|
17
17
|
@sort_columns = [:title, :name]
|
18
18
|
@executed = false
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
def execute
|
22
22
|
@executed = true
|
23
23
|
@query = @model
|
24
|
-
|
24
|
+
|
25
25
|
filter
|
26
26
|
sorting
|
27
27
|
limit
|
28
|
-
|
28
|
+
|
29
29
|
return @query
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def json(final_query = nil)
|
33
33
|
unless final_query
|
34
34
|
execute unless @executed
|
35
35
|
final_query = @query
|
36
36
|
end
|
37
|
-
|
38
|
-
dis_rec_count = final_query.limit(nil).count
|
37
|
+
|
38
|
+
dis_rec_count = final_query.limit(nil).count
|
39
39
|
dis_rec_count = dis_rec_count.length if dis_rec_count.is_a?(Hash)
|
40
|
-
|
40
|
+
|
41
41
|
res = {
|
42
42
|
:sEcho => @dts[:sEcho] ? @dts[:sEcho].to_i : 1,
|
43
43
|
:iTotalRecords => @model.count,
|
@@ -45,20 +45,27 @@ class ActiveRecordDataTables
|
|
45
45
|
:aaData => []
|
46
46
|
}
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
private
|
50
|
-
|
50
|
+
|
51
|
+
# Checks the given parameters for filters and manipulates the query based on it.
|
51
52
|
def filter
|
52
53
|
@filter_params.each do |key, val|
|
53
|
-
if
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
# Strip empty values from the array if the given value is an array.
|
55
|
+
val.select!{ |val| !val.to_s.empty? } if val.is_a?(Array)
|
56
|
+
|
57
|
+
# Convert key if it starts with a column name.
|
58
|
+
key = key.slice(@model_method_name.length + 1, key.length) if key.start_with?("#{@model_method_name}_")
|
59
|
+
|
57
60
|
if @force_filter_for && @force_filter_for.include?(key)
|
58
61
|
ret = @args[:filter].call(:key => key, :val => val, :query => @query)
|
59
62
|
@query = ret if ret
|
60
63
|
elsif @model.column_names.include?(key)
|
61
|
-
|
64
|
+
if val.is_a?(Array) && val.empty?
|
65
|
+
# Ignore.
|
66
|
+
else
|
67
|
+
@query = @query.where(key => val)
|
68
|
+
end
|
62
69
|
elsif match = key.to_s.match(/^(.+)_like$/) and @model.column_names.include?(match[1])
|
63
70
|
next if val.blank?
|
64
71
|
table = @model.arel_table
|
@@ -71,48 +78,50 @@ class ActiveRecordDataTables
|
|
71
78
|
end
|
72
79
|
end
|
73
80
|
end
|
74
|
-
|
81
|
+
|
82
|
+
# Checks the given parameters for limits and manipulates the query based on it.
|
75
83
|
def limit
|
76
84
|
raise "'iDisplayStart' was not given? #{@dts}" unless @dts.key?("iDisplayStart")
|
77
85
|
raise "'iDisplayEnd' was not given? #{@dts}" unless @dts.key?("iDisplayLength")
|
78
|
-
|
86
|
+
|
79
87
|
disp_start = @dts["iDisplayStart"].to_i
|
80
88
|
disp_length = @dts["iDisplayLength"].to_i
|
81
|
-
|
89
|
+
|
82
90
|
@query = @query.page((disp_start / disp_length) + 1).per(disp_length)
|
83
91
|
end
|
84
|
-
|
92
|
+
|
93
|
+
# Checks the given parameters for sorting and manipulates the query based on it.
|
85
94
|
def sorting
|
86
95
|
sort_no = 0
|
87
96
|
sorts = []
|
88
|
-
|
97
|
+
|
89
98
|
loop do
|
90
99
|
sorted = false
|
91
100
|
name_col = "iSortCol_#{sort_no}"
|
92
101
|
name_mode = "sSortDir_#{sort_no}"
|
93
102
|
sort_col = @dts[name_col]
|
94
103
|
break if !sort_col
|
95
|
-
|
104
|
+
|
96
105
|
col_name = @columns[sort_col.to_i]
|
97
106
|
next if !col_name
|
98
|
-
|
107
|
+
|
99
108
|
if @dts[name_mode] == "desc"
|
100
109
|
sort_mode = "DESC"
|
101
110
|
else
|
102
111
|
sort_mode = "ASC"
|
103
112
|
end
|
104
|
-
|
113
|
+
|
105
114
|
if match = col_name.to_s.match(/^(.+)_id$/)
|
106
115
|
method_name = match[1]
|
107
116
|
sub_model_name = StringCases.snake_to_camel(col_name.slice(0, col_name.length - 3))
|
108
|
-
|
117
|
+
|
109
118
|
if Kernel.const_defined?(sub_model_name)
|
110
119
|
sub_model_const = Kernel.const_get(sub_model_name)
|
111
120
|
unless @joins.key?(method_name)
|
112
121
|
@query = @query.includes(method_name)
|
113
122
|
@joins[method_name] = true
|
114
123
|
end
|
115
|
-
|
124
|
+
|
116
125
|
@sort_columns.each do |sort_col_name|
|
117
126
|
if sub_model_const.column_names.include?(sort_col_name.to_s)
|
118
127
|
sorts << "`#{sub_model_const.table_name}`.`#{escape_col(sort_col_name)}` #{sort_mode}"
|
@@ -122,7 +131,7 @@ class ActiveRecordDataTables
|
|
122
131
|
end
|
123
132
|
end
|
124
133
|
end
|
125
|
-
|
134
|
+
|
126
135
|
if @model.column_names.include?(col_name.to_s)
|
127
136
|
sorts << "`#{@model.table_name}`.`#{escape_col(col_name)}` #{sort_mode}"
|
128
137
|
elsif @args[:sort]
|
@@ -131,17 +140,19 @@ class ActiveRecordDataTables
|
|
131
140
|
else
|
132
141
|
raise "Unknown sort-column: '#{col_name}'."
|
133
142
|
end
|
134
|
-
|
143
|
+
|
135
144
|
sort_no += 1
|
136
145
|
end
|
137
|
-
|
146
|
+
|
138
147
|
@query = @query.order(sorts.join(", "))
|
139
148
|
end
|
140
|
-
|
149
|
+
|
150
|
+
# Escapes the given string to be used in a SQL statement.
|
141
151
|
def escape(str)
|
142
152
|
return ActiveRecord::Base.connection.quote(str).slice(1, str.length - 1)
|
143
153
|
end
|
144
|
-
|
154
|
+
|
155
|
+
# Escapes the given name as a column and checks for SQL-injections.
|
145
156
|
def escape_col(name)
|
146
157
|
raise "Possible SQL injection hack: '#{name}'." unless name.to_s.match(/\A[A-z\d_]+\Z/)
|
147
158
|
return name
|
metadata
CHANGED
@@ -2,95 +2,95 @@
|
|
2
2
|
name: active-record-data-tables
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- kaspernj
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
+
prerelease: false
|
16
|
+
name: string-cases
|
17
|
+
type: :runtime
|
15
18
|
version_requirements: !ruby/object:Gem::Requirement
|
16
|
-
none: false
|
17
19
|
requirements:
|
18
20
|
- - ! '>='
|
19
21
|
- !ruby/object:Gem::Version
|
20
22
|
version: '0'
|
21
|
-
name: string-cases
|
22
|
-
type: :runtime
|
23
|
-
prerelease: false
|
24
|
-
requirement: !ruby/object:Gem::Requirement
|
25
23
|
none: false
|
24
|
+
requirement: !ruby/object:Gem::Requirement
|
26
25
|
requirements:
|
27
26
|
- - ! '>='
|
28
27
|
- !ruby/object:Gem::Version
|
29
28
|
version: '0'
|
29
|
+
none: false
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
+
prerelease: false
|
32
|
+
name: rspec
|
33
|
+
type: :development
|
31
34
|
version_requirements: !ruby/object:Gem::Requirement
|
32
|
-
none: false
|
33
35
|
requirements:
|
34
36
|
- - ~>
|
35
37
|
- !ruby/object:Gem::Version
|
36
38
|
version: 2.8.0
|
37
|
-
name: rspec
|
38
|
-
type: :development
|
39
|
-
prerelease: false
|
40
|
-
requirement: !ruby/object:Gem::Requirement
|
41
39
|
none: false
|
40
|
+
requirement: !ruby/object:Gem::Requirement
|
42
41
|
requirements:
|
43
42
|
- - ~>
|
44
43
|
- !ruby/object:Gem::Version
|
45
44
|
version: 2.8.0
|
45
|
+
none: false
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
|
+
prerelease: false
|
48
|
+
name: rdoc
|
49
|
+
type: :development
|
47
50
|
version_requirements: !ruby/object:Gem::Requirement
|
48
|
-
none: false
|
49
51
|
requirements:
|
50
52
|
- - ~>
|
51
53
|
- !ruby/object:Gem::Version
|
52
54
|
version: '3.12'
|
53
|
-
name: rdoc
|
54
|
-
type: :development
|
55
|
-
prerelease: false
|
56
|
-
requirement: !ruby/object:Gem::Requirement
|
57
55
|
none: false
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
58
57
|
requirements:
|
59
58
|
- - ~>
|
60
59
|
- !ruby/object:Gem::Version
|
61
60
|
version: '3.12'
|
61
|
+
none: false
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
|
+
prerelease: false
|
64
|
+
name: bundler
|
65
|
+
type: :development
|
63
66
|
version_requirements: !ruby/object:Gem::Requirement
|
64
|
-
none: false
|
65
67
|
requirements:
|
66
68
|
- - ! '>='
|
67
69
|
- !ruby/object:Gem::Version
|
68
70
|
version: 1.0.0
|
69
|
-
name: bundler
|
70
|
-
type: :development
|
71
|
-
prerelease: false
|
72
|
-
requirement: !ruby/object:Gem::Requirement
|
73
71
|
none: false
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
74
73
|
requirements:
|
75
74
|
- - ! '>='
|
76
75
|
- !ruby/object:Gem::Version
|
77
76
|
version: 1.0.0
|
77
|
+
none: false
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
|
+
prerelease: false
|
80
|
+
name: jeweler
|
81
|
+
type: :development
|
79
82
|
version_requirements: !ruby/object:Gem::Requirement
|
80
|
-
none: false
|
81
83
|
requirements:
|
82
84
|
- - ~>
|
83
85
|
- !ruby/object:Gem::Version
|
84
86
|
version: 1.8.4
|
85
|
-
name: jeweler
|
86
|
-
type: :development
|
87
|
-
prerelease: false
|
88
|
-
requirement: !ruby/object:Gem::Requirement
|
89
87
|
none: false
|
88
|
+
requirement: !ruby/object:Gem::Requirement
|
90
89
|
requirements:
|
91
90
|
- - ~>
|
92
91
|
- !ruby/object:Gem::Version
|
93
92
|
version: 1.8.4
|
93
|
+
none: false
|
94
94
|
description: Helping functionality for filtering, sorting and stuff like that with
|
95
95
|
data-tables and ActiveRecord.
|
96
96
|
email: k@spernj.org
|
@@ -120,20 +120,20 @@ rdoc_options: []
|
|
120
120
|
require_paths:
|
121
121
|
- lib
|
122
122
|
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
-
none: false
|
124
123
|
requirements:
|
125
124
|
- - ! '>='
|
126
125
|
- !ruby/object:Gem::Version
|
127
126
|
segments:
|
128
127
|
- 0
|
129
|
-
hash:
|
128
|
+
hash: -1808048283140226905
|
130
129
|
version: '0'
|
131
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
130
|
none: false
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
132
|
requirements:
|
134
133
|
- - ! '>='
|
135
134
|
- !ruby/object:Gem::Version
|
136
135
|
version: '0'
|
136
|
+
none: false
|
137
137
|
requirements: []
|
138
138
|
rubyforge_project:
|
139
139
|
rubygems_version: 1.8.23
|