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 CHANGED
@@ -1 +1 @@
1
- 0.0.1
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.1"
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-06-04"
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 key.start_with?("#{@model_method_name}_")
54
- key = key.slice(@model_method_name.length + 1, key.length)
55
- end
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
- @query = @query.where(key => val)
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.1
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-06-04 00:00:00.000000000 Z
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: 2526805225709928991
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