ajax-datatables-rails 0.3.1 → 0.4.0
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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +26 -0
- data/.gitignore +20 -0
- data/.rspec +1 -0
- data/.rubocop.yml +1157 -0
- data/.travis.yml +68 -0
- data/Appraisals +34 -0
- data/Gemfile +5 -1
- data/LICENSE +17 -18
- data/README.md +239 -239
- data/Rakefile +1 -1
- data/ajax-datatables-rails.gemspec +31 -24
- data/gemfiles/rails_4.0.13.gemfile +14 -0
- data/gemfiles/rails_4.1.15.gemfile +14 -0
- data/gemfiles/rails_4.2.8.gemfile +13 -0
- data/gemfiles/rails_5.0.3.gemfile +13 -0
- data/gemfiles/rails_5.1.1.gemfile +13 -0
- data/lib/ajax-datatables-rails.rb +9 -8
- data/lib/ajax-datatables-rails/base.rb +80 -156
- data/lib/ajax-datatables-rails/config.rb +8 -5
- data/lib/ajax-datatables-rails/datatable/column.rb +169 -0
- data/lib/ajax-datatables-rails/datatable/column_date_filter.rb +41 -0
- data/lib/ajax-datatables-rails/datatable/datatable.rb +79 -0
- data/lib/ajax-datatables-rails/datatable/simple_order.rb +31 -0
- data/lib/ajax-datatables-rails/datatable/simple_search.rb +18 -0
- data/lib/ajax-datatables-rails/orm/active_record.rb +52 -0
- data/lib/ajax-datatables-rails/version.rb +1 -1
- data/lib/generators/datatable/templates/ajax_datatables_rails_config.rb +3 -3
- data/lib/generators/rails/datatable_generator.rb +7 -19
- data/lib/generators/rails/templates/datatable.rb +26 -14
- data/spec/ajax-datatables-rails/base_spec.rb +190 -0
- data/spec/ajax-datatables-rails/configuration_spec.rb +43 -0
- data/spec/ajax-datatables-rails/datatable/column_spec.rb +109 -0
- data/spec/ajax-datatables-rails/datatable/datatable_spec.rb +87 -0
- data/spec/ajax-datatables-rails/datatable/simple_order_spec.rb +13 -0
- data/spec/ajax-datatables-rails/datatable/simple_search_spec.rb +17 -0
- data/spec/ajax-datatables-rails/extended_spec.rb +20 -0
- data/spec/ajax-datatables-rails/orm/active_record_filter_records_spec.rb +439 -0
- data/spec/ajax-datatables-rails/orm/active_record_paginate_records_spec.rb +66 -0
- data/spec/ajax-datatables-rails/orm/active_record_sort_records_spec.rb +34 -0
- data/spec/ajax-datatables-rails/orm/active_record_spec.rb +25 -0
- data/spec/factories/user.rb +9 -0
- data/spec/install_oracle.sh +12 -0
- data/spec/spec_helper.rb +75 -3
- data/spec/support/schema.rb +14 -0
- data/spec/support/test_helpers.rb +174 -0
- data/spec/support/test_models.rb +2 -0
- metadata +169 -37
- data/lib/ajax-datatables-rails/extensions/kaminari.rb +0 -12
- data/lib/ajax-datatables-rails/extensions/simple_paginator.rb +0 -12
- data/lib/ajax-datatables-rails/extensions/will_paginate.rb +0 -12
- data/lib/ajax-datatables-rails/models.rb +0 -6
- data/spec/ajax-datatables-rails/ajax_datatables_rails_spec.rb +0 -351
- data/spec/ajax-datatables-rails/kaminari_spec.rb +0 -35
- data/spec/ajax-datatables-rails/models_spec.rb +0 -10
- data/spec/ajax-datatables-rails/simple_paginator_spec.rb +0 -32
- data/spec/ajax-datatables-rails/will_paginate_spec.rb +0 -28
- data/spec/schema.rb +0 -35
- data/spec/test_models.rb +0 -21
data/Rakefile
CHANGED
@@ -1,30 +1,37 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
1
|
+
# coding: utf-8
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
4
3
|
require 'ajax-datatables-rails/version'
|
5
4
|
|
6
|
-
Gem::Specification.new do |
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'ajax-datatables-rails'
|
7
|
+
s.version = AjaxDatatablesRails::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ['Joel Quenneville', 'Antonio Antillon']
|
10
|
+
s.email = ['joel.quenneville@collegeplus.org', 'antillas21@gmail.com']
|
11
|
+
s.homepage = 'https://github.com/jbox-web/ajax-datatables-rails'
|
12
|
+
s.summary = %q{A gem that simplifies using datatables and hundreds of records via ajax}
|
13
|
+
s.description = %q{A wrapper around datatable's ajax methods that allow synchronization with server-side pagination in a rails app}
|
14
|
+
s.license = 'MIT'
|
15
15
|
|
16
|
-
|
17
|
-
gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
-
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
-
gem.require_path = "lib"
|
16
|
+
s.add_dependency 'railties', '>= 4.0'
|
20
17
|
|
21
|
-
|
18
|
+
s.add_development_dependency 'rails', '>= 4.0'
|
19
|
+
s.add_development_dependency 'rake'
|
20
|
+
s.add_development_dependency 'pg'
|
21
|
+
s.add_development_dependency 'mysql2'
|
22
|
+
s.add_development_dependency 'sqlite3'
|
23
|
+
s.add_development_dependency 'activerecord-oracle_enhanced-adapter'
|
24
|
+
s.add_development_dependency 'rspec'
|
25
|
+
s.add_development_dependency 'generator_spec'
|
26
|
+
s.add_development_dependency 'pry'
|
27
|
+
s.add_development_dependency 'simplecov'
|
28
|
+
s.add_development_dependency 'database_cleaner'
|
29
|
+
s.add_development_dependency 'factory_girl'
|
30
|
+
s.add_development_dependency 'faker'
|
31
|
+
s.add_development_dependency 'appraisal'
|
22
32
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
gem.add_development_dependency "sqlite3"
|
28
|
-
gem.add_development_dependency "rails", ">= 3.1.0"
|
29
|
-
gem.add_development_dependency "activerecord", ">= 4.1.6"
|
33
|
+
s.files = `git ls-files`.split("\n")
|
34
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
35
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
36
|
+
s.require_paths = ['lib']
|
30
37
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "rails", "4.0.13"
|
6
|
+
gem "mysql2", "~> 0.3.18"
|
7
|
+
gem "activerecord-oracle_enhanced-adapter", "~> 1.5.0"
|
8
|
+
gem "ruby-oci8" if ENV["DB_ADAPTER"] == "oracle_enhanced"
|
9
|
+
|
10
|
+
group :test do
|
11
|
+
gem "codeclimate-test-reporter", "~> 1.0.0"
|
12
|
+
end
|
13
|
+
|
14
|
+
gemspec path: "../"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "rails", "4.1.15"
|
6
|
+
gem "mysql2", "~> 0.3.18"
|
7
|
+
gem "activerecord-oracle_enhanced-adapter", "~> 1.5.0"
|
8
|
+
gem "ruby-oci8" if ENV["DB_ADAPTER"] == "oracle_enhanced"
|
9
|
+
|
10
|
+
group :test do
|
11
|
+
gem "codeclimate-test-reporter", "~> 1.0.0"
|
12
|
+
end
|
13
|
+
|
14
|
+
gemspec path: "../"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "rails", "4.2.8"
|
6
|
+
gem "activerecord-oracle_enhanced-adapter", "~> 1.6.0"
|
7
|
+
gem "ruby-oci8" if ENV["DB_ADAPTER"] == "oracle_enhanced"
|
8
|
+
|
9
|
+
group :test do
|
10
|
+
gem "codeclimate-test-reporter", "~> 1.0.0"
|
11
|
+
end
|
12
|
+
|
13
|
+
gemspec path: "../"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "rails", "5.0.3"
|
6
|
+
gem "activerecord-oracle_enhanced-adapter", "~> 1.7.0"
|
7
|
+
gem "ruby-oci8" if ENV["DB_ADAPTER"] == "oracle_enhanced"
|
8
|
+
|
9
|
+
group :test do
|
10
|
+
gem "codeclimate-test-reporter", "~> 1.0.0"
|
11
|
+
end
|
12
|
+
|
13
|
+
gemspec path: "../"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "rails", "5.1.1"
|
6
|
+
gem "activerecord-oracle_enhanced-adapter", "~> 1.8.0"
|
7
|
+
gem "ruby-oci8" if ENV["DB_ADAPTER"] == "oracle_enhanced"
|
8
|
+
|
9
|
+
group :test do
|
10
|
+
gem "codeclimate-test-reporter", "~> 1.0.0"
|
11
|
+
end
|
12
|
+
|
13
|
+
gemspec path: "../"
|
@@ -1,10 +1,11 @@
|
|
1
|
-
require 'ajax-datatables-rails/version'
|
2
|
-
require 'ajax-datatables-rails/config'
|
3
|
-
require 'ajax-datatables-rails/models'
|
4
|
-
require 'ajax-datatables-rails/base'
|
5
|
-
require 'ajax-datatables-rails/extensions/simple_paginator'
|
6
|
-
require 'ajax-datatables-rails/extensions/kaminari'
|
7
|
-
require 'ajax-datatables-rails/extensions/will_paginate'
|
8
|
-
|
9
1
|
module AjaxDatatablesRails
|
2
|
+
require 'ajax-datatables-rails/version'
|
3
|
+
require 'ajax-datatables-rails/config'
|
4
|
+
require 'ajax-datatables-rails/base'
|
5
|
+
require 'ajax-datatables-rails/datatable/datatable'
|
6
|
+
require 'ajax-datatables-rails/datatable/simple_search'
|
7
|
+
require 'ajax-datatables-rails/datatable/simple_order'
|
8
|
+
require 'ajax-datatables-rails/datatable/column_date_filter' unless AjaxDatatablesRails.old_rails?
|
9
|
+
require 'ajax-datatables-rails/datatable/column'
|
10
|
+
require 'ajax-datatables-rails/orm/active_record'
|
10
11
|
end
|
@@ -1,214 +1,138 @@
|
|
1
1
|
module AjaxDatatablesRails
|
2
|
+
class NotImplemented < StandardError; end
|
3
|
+
|
2
4
|
class Base
|
3
5
|
extend Forwardable
|
4
|
-
class MethodNotImplementedError < StandardError; end
|
5
6
|
|
6
|
-
attr_reader :view, :options
|
7
|
-
def_delegator :@view, :params
|
7
|
+
attr_reader :view, :options
|
8
|
+
def_delegator :@view, :params
|
8
9
|
|
9
10
|
def initialize(view, options = {})
|
10
|
-
@view
|
11
|
+
@view = view
|
11
12
|
@options = options
|
12
|
-
|
13
|
+
load_orm_extension
|
13
14
|
end
|
14
15
|
|
15
16
|
def config
|
16
17
|
@config ||= AjaxDatatablesRails.config
|
17
18
|
end
|
18
19
|
|
19
|
-
def
|
20
|
-
@
|
21
|
-
end
|
22
|
-
|
23
|
-
def searchable_columns
|
24
|
-
@searchable_columns ||= []
|
20
|
+
def datatable
|
21
|
+
@datatable ||= Datatable::Datatable.new(self)
|
25
22
|
end
|
26
23
|
|
27
|
-
def
|
28
|
-
fail(
|
29
|
-
MethodNotImplementedError,
|
30
|
-
'Please implement this method in your class.'
|
31
|
-
)
|
24
|
+
def view_columns
|
25
|
+
fail(NotImplemented, view_columns_error_text)
|
32
26
|
end
|
33
27
|
|
34
28
|
def get_raw_records
|
35
|
-
fail(
|
36
|
-
MethodNotImplementedError,
|
37
|
-
'Please implement this method in your class.'
|
38
|
-
)
|
29
|
+
fail(NotImplemented, raw_records_error_text)
|
39
30
|
end
|
40
31
|
|
41
|
-
def
|
42
|
-
|
43
|
-
:draw => params[:draw].to_i,
|
44
|
-
:recordsTotal => get_raw_records.count(:all),
|
45
|
-
:recordsFiltered => filter_records(get_raw_records).count(:all),
|
46
|
-
:data => data
|
47
|
-
}
|
32
|
+
def data
|
33
|
+
fail(NotImplemented, data_error_text)
|
48
34
|
end
|
49
35
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
53
|
-
if(respond_to?(:logger) && logger.present?)
|
54
|
-
logger.warn(warning)
|
55
|
-
else
|
56
|
-
warn(warning)
|
57
|
-
end
|
36
|
+
def additional_datas
|
37
|
+
{}
|
58
38
|
end
|
59
39
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
40
|
+
def as_json(*)
|
41
|
+
{
|
42
|
+
recordsTotal: records_total_count,
|
43
|
+
recordsFiltered: records_filtered_count,
|
44
|
+
data: sanitize(data)
|
45
|
+
}.merge(additional_datas)
|
64
46
|
end
|
65
47
|
|
66
|
-
def
|
67
|
-
records
|
68
|
-
records = sort_records(records) if params[:order].present?
|
69
|
-
records = filter_records(records) if params[:search].present?
|
70
|
-
records = paginate_records(records) unless params[:length].present? && params[:length] == '-1'
|
71
|
-
records
|
48
|
+
def records
|
49
|
+
@records ||= retrieve_records
|
72
50
|
end
|
73
51
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
52
|
+
# helper methods
|
53
|
+
def connected_columns
|
54
|
+
@connected_columns ||= begin
|
55
|
+
view_columns.keys.map do |field_name|
|
56
|
+
datatable.column_by(:data, field_name.to_s)
|
57
|
+
end.compact
|
78
58
|
end
|
79
|
-
records.order(sort_by.join(", "))
|
80
|
-
end
|
81
|
-
|
82
|
-
def paginate_records(records)
|
83
|
-
fail(
|
84
|
-
MethodNotImplementedError,
|
85
|
-
'Please mixin a pagination extension.'
|
86
|
-
)
|
87
|
-
end
|
88
|
-
|
89
|
-
def filter_records(records)
|
90
|
-
records = simple_search(records)
|
91
|
-
records = composite_search(records)
|
92
|
-
records
|
93
|
-
end
|
94
|
-
|
95
|
-
def simple_search(records)
|
96
|
-
return records unless (params[:search].present? && params[:search][:value].present?)
|
97
|
-
conditions = build_conditions_for(params[:search][:value])
|
98
|
-
records = records.where(conditions) if conditions
|
99
|
-
records
|
100
59
|
end
|
101
60
|
|
102
|
-
def
|
103
|
-
|
104
|
-
|
105
|
-
records
|
106
|
-
end
|
107
|
-
|
108
|
-
def build_conditions_for(query)
|
109
|
-
search_for = query.split(' ')
|
110
|
-
criteria = search_for.inject([]) do |criteria, atom|
|
111
|
-
criteria << searchable_columns.map { |col| search_condition(col, atom) }.reduce(:or)
|
112
|
-
end.reduce(:and)
|
113
|
-
criteria
|
114
|
-
end
|
115
|
-
|
116
|
-
def search_condition(column, value)
|
117
|
-
if column[0] == column.downcase[0]
|
118
|
-
::AjaxDatatablesRails::Base.deprecated '[DEPRECATED] Using table_name.column_name notation is deprecated. Please refer to: https://github.com/antillas21/ajax-datatables-rails#searchable-and-sortable-columns-syntax'
|
119
|
-
return deprecated_search_condition(column, value)
|
120
|
-
else
|
121
|
-
return new_search_condition(column, value)
|
61
|
+
def searchable_columns
|
62
|
+
@searchable_columns ||= begin
|
63
|
+
connected_columns.select(&:searchable?)
|
122
64
|
end
|
123
65
|
end
|
124
66
|
|
125
|
-
def
|
126
|
-
|
127
|
-
|
128
|
-
casted_column = ::Arel::Nodes::NamedFunction.new('CAST', [model.arel_table[column.to_sym].as(typecast)])
|
129
|
-
casted_column.matches("%#{value}%")
|
130
|
-
end
|
131
|
-
|
132
|
-
def deprecated_search_condition(column, value)
|
133
|
-
model, column = column.split('.')
|
134
|
-
model = model.singularize.titleize.gsub( / /, '' ).constantize
|
135
|
-
|
136
|
-
casted_column = ::Arel::Nodes::NamedFunction.new('CAST', [model.arel_table[column.to_sym].as(typecast)])
|
137
|
-
casted_column.matches("%#{value}%")
|
138
|
-
end
|
139
|
-
|
140
|
-
def aggregate_query
|
141
|
-
conditions = searchable_columns.each_with_index.map do |column, index|
|
142
|
-
value = params[:columns]["#{index}"][:search][:value] if params[:columns]
|
143
|
-
search_condition(column, value) unless value.blank?
|
67
|
+
def search_columns
|
68
|
+
@search_columns ||= begin
|
69
|
+
searchable_columns.select(&:searched?)
|
144
70
|
end
|
145
|
-
conditions.compact.reduce(:and)
|
146
71
|
end
|
147
72
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
73
|
+
private
|
74
|
+
|
75
|
+
def sanitize(data)
|
76
|
+
data.map do |record|
|
77
|
+
if record.is_a?(Array)
|
78
|
+
record.map { |td| ERB::Util.html_escape(td) }
|
79
|
+
else
|
80
|
+
record.update(record){ |_, v| ERB::Util.html_escape(v) }
|
81
|
+
end
|
154
82
|
end
|
155
83
|
end
|
156
84
|
|
157
|
-
def
|
158
|
-
|
85
|
+
def retrieve_records
|
86
|
+
records = fetch_records
|
87
|
+
records = filter_records(records)
|
88
|
+
records = sort_records(records) if datatable.orderable?
|
89
|
+
records = paginate_records(records) if datatable.paginate?
|
90
|
+
records
|
159
91
|
end
|
160
92
|
|
161
|
-
def
|
162
|
-
(
|
93
|
+
def records_total_count
|
94
|
+
get_raw_records.count(:all)
|
163
95
|
end
|
164
96
|
|
165
|
-
def
|
166
|
-
|
97
|
+
def records_filtered_count
|
98
|
+
filter_records(get_raw_records).count(:all)
|
167
99
|
end
|
168
100
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
101
|
+
# Private helper methods
|
102
|
+
def load_orm_extension
|
103
|
+
case config.orm
|
104
|
+
when :mongoid then nil
|
105
|
+
when :active_record then extend ORM::ActiveRecord
|
106
|
+
else
|
107
|
+
nil
|
108
|
+
end
|
174
109
|
end
|
175
110
|
|
176
|
-
def
|
177
|
-
|
178
|
-
end
|
111
|
+
def raw_records_error_text
|
112
|
+
return <<-eos
|
179
113
|
|
180
|
-
|
181
|
-
|
182
|
-
|
114
|
+
You should implement this method in your class and specify
|
115
|
+
how records are going to be retrieved from the database.
|
116
|
+
eos
|
183
117
|
end
|
184
118
|
|
185
|
-
def
|
186
|
-
|
187
|
-
options.include?(item[:dir]) ? item[:dir].upcase : 'ASC'
|
188
|
-
end
|
119
|
+
def data_error_text
|
120
|
+
return <<-eos
|
189
121
|
|
190
|
-
|
191
|
-
|
122
|
+
You should implement this method in your class and return an array
|
123
|
+
of arrays, or an array of hashes, as defined in the jQuery.dataTables
|
124
|
+
plugin documentation.
|
125
|
+
eos
|
192
126
|
end
|
193
127
|
|
194
|
-
def
|
195
|
-
|
196
|
-
params[:columns].each_value do |column|
|
197
|
-
@sortable_displayed_columns << column[:data] if column[:orderable] == 'true'
|
198
|
-
end
|
199
|
-
@sortable_displayed_columns
|
200
|
-
end
|
128
|
+
def view_columns_error_text
|
129
|
+
return <<-eos
|
201
130
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
extend Extensions::WillPaginate
|
208
|
-
else
|
209
|
-
extend Extensions::SimplePaginator
|
210
|
-
end
|
211
|
-
self
|
131
|
+
You should implement this method in your class and return an array
|
132
|
+
of database columns based on the columns displayed in the HTML view.
|
133
|
+
These columns should be represented in the ModelName.column_name,
|
134
|
+
or aliased_join_table.column_name notation.
|
135
|
+
eos
|
212
136
|
end
|
213
137
|
end
|
214
138
|
end
|