active-record-data-tables 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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