ajax-datatables-rails 0.4.3 → 1.3.1
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/.github/workflows/ci.yml +120 -0
- data/.rubocop.yml +17 -7
- data/Appraisals +15 -20
- data/CHANGELOG.md +54 -1
- data/Gemfile +0 -5
- data/Guardfile +16 -0
- data/README.md +238 -112
- data/Rakefile +1 -0
- data/ajax-datatables-rails.gemspec +24 -20
- data/bin/_guard-core +29 -0
- data/bin/appraisal +29 -0
- data/bin/bundle +114 -0
- data/bin/guard +29 -0
- data/bin/rake +29 -0
- data/bin/rspec +29 -0
- data/bin/rubocop +29 -0
- data/doc/migrate.md +97 -0
- data/doc/webpack.md +7 -2
- data/gemfiles/{rails_5.2.0.gemfile → rails_5.2.4.gemfile} +3 -5
- data/gemfiles/{rails_5.0.7.gemfile → rails_6.0.3.gemfile} +4 -6
- data/gemfiles/{rails_5.1.6.gemfile → rails_6.1.0.gemfile} +4 -6
- data/lib/ajax-datatables-rails.rb +12 -1
- data/lib/ajax-datatables-rails/active_record.rb +7 -0
- data/lib/ajax-datatables-rails/base.rb +47 -46
- data/lib/ajax-datatables-rails/datatable.rb +6 -0
- data/lib/ajax-datatables-rails/datatable/column.rb +65 -20
- data/lib/ajax-datatables-rails/datatable/column/date_filter.rb +12 -21
- data/lib/ajax-datatables-rails/datatable/column/order.rb +1 -1
- data/lib/ajax-datatables-rails/datatable/column/search.rb +37 -22
- data/lib/ajax-datatables-rails/datatable/datatable.rb +16 -7
- data/lib/ajax-datatables-rails/datatable/simple_order.rb +23 -10
- data/lib/ajax-datatables-rails/datatable/simple_search.rb +2 -0
- data/lib/ajax-datatables-rails/error.rb +9 -0
- data/lib/ajax-datatables-rails/orm.rb +6 -0
- data/lib/ajax-datatables-rails/orm/active_record.rb +11 -12
- data/lib/ajax-datatables-rails/version.rb +13 -1
- data/lib/generators/rails/templates/datatable.rb +1 -1
- data/spec/ajax-datatables-rails/base_spec.rb +129 -93
- data/spec/ajax-datatables-rails/datatable/column_spec.rb +105 -37
- data/spec/ajax-datatables-rails/datatable/datatable_spec.rb +71 -31
- data/spec/ajax-datatables-rails/datatable/simple_order_spec.rb +36 -14
- data/spec/ajax-datatables-rails/datatable/simple_search_spec.rb +4 -2
- data/spec/ajax-datatables-rails/orm/active_record_filter_records_spec.rb +315 -272
- data/spec/ajax-datatables-rails/orm/active_record_paginate_records_spec.rb +9 -8
- data/spec/ajax-datatables-rails/orm/active_record_sort_records_spec.rb +17 -14
- data/spec/factories/user.rb +3 -1
- data/spec/install_oracle.sh +9 -3
- data/spec/spec_helper.rb +33 -28
- data/spec/support/datatables/complex_datatable.rb +31 -0
- data/spec/support/datatables/complex_datatable_array.rb +16 -0
- data/spec/support/{datatable_cond_date.rb → datatables/datatable_cond_date.rb} +2 -0
- data/spec/support/{datatable_cond_numeric.rb → datatables/datatable_cond_numeric.rb} +3 -1
- data/spec/support/{datatable_cond_proc.rb → datatables/datatable_cond_proc.rb} +2 -0
- data/spec/support/{datatable_cond_string.rb → datatables/datatable_cond_string.rb} +9 -1
- data/spec/support/datatables/datatable_cond_unknown.rb +7 -0
- data/spec/support/{datatable_order_nulls_last.rb → datatables/datatable_order_nulls_last.rb} +2 -0
- data/spec/support/{test_helpers.rb → helpers/params.rb} +17 -42
- data/spec/support/{test_models.rb → models/user.rb} +2 -0
- data/spec/support/schema.rb +3 -1
- metadata +76 -75
- data/.travis.yml +0 -80
- data/gemfiles/rails_4.0.13.gemfile +0 -14
- data/gemfiles/rails_4.1.16.gemfile +0 -14
- data/gemfiles/rails_4.2.10.gemfile +0 -14
- data/lib/ajax-datatables-rails/config.rb +0 -31
- data/lib/ajax_datatables_rails.rb +0 -15
- data/lib/generators/datatable/config_generator.rb +0 -19
- data/lib/generators/datatable/templates/ajax_datatables_rails_config.rb +0 -12
- data/spec/ajax-datatables-rails/configuration_spec.rb +0 -43
- data/spec/ajax-datatables-rails/extended_spec.rb +0 -20
- data/spec/ajax-datatables-rails/orm/active_record_spec.rb +0 -25
@@ -1,12 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
|
-
describe AjaxDatatablesRails::ORM::ActiveRecord do
|
5
|
+
RSpec.describe AjaxDatatablesRails::ORM::ActiveRecord do
|
4
6
|
|
5
|
-
let(:
|
6
|
-
let(:datatable) { ComplexDatatable.new(view) }
|
7
|
+
let(:datatable) { ComplexDatatable.new(sample_params) }
|
7
8
|
let(:records) { User.all }
|
8
9
|
|
9
|
-
before
|
10
|
+
before do
|
10
11
|
create(:user, username: 'johndoe', email: 'johndoe@example.com')
|
11
12
|
create(:user, username: 'msmith', email: 'mary.smith@example.com')
|
12
13
|
end
|
@@ -17,8 +18,8 @@ describe AjaxDatatablesRails::ORM::ActiveRecord do
|
|
17
18
|
end
|
18
19
|
|
19
20
|
it 'paginates records properly' do
|
20
|
-
if
|
21
|
-
if Rails.version.in? %w[4.
|
21
|
+
if ENV['DB_ADAPTER'] == 'oracle_enhanced'
|
22
|
+
if Rails.version.in? %w[4.2.11]
|
22
23
|
expect(datatable.paginate_records(records).to_sql).to include(
|
23
24
|
'rownum <= 10'
|
24
25
|
)
|
@@ -35,8 +36,8 @@ describe AjaxDatatablesRails::ORM::ActiveRecord do
|
|
35
36
|
|
36
37
|
datatable.params[:start] = '26'
|
37
38
|
datatable.params[:length] = '25'
|
38
|
-
if
|
39
|
-
if Rails.version.in? %w[4.
|
39
|
+
if ENV['DB_ADAPTER'] == 'oracle_enhanced'
|
40
|
+
if Rails.version.in? %w[4.2.11]
|
40
41
|
expect(datatable.paginate_records(records).to_sql).to include(
|
41
42
|
'rownum <= 51'
|
42
43
|
)
|
@@ -1,13 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
|
-
describe AjaxDatatablesRails::ORM::ActiveRecord do
|
5
|
+
RSpec.describe AjaxDatatablesRails::ORM::ActiveRecord do
|
4
6
|
|
5
|
-
let(:
|
6
|
-
let(:
|
7
|
-
let(:nulls_last_datatable) { DatatableOrderNullsLast.new(view) }
|
7
|
+
let(:datatable) { ComplexDatatable.new(sample_params) }
|
8
|
+
let(:nulls_last_datatable) { DatatableOrderNullsLast.new(sample_params) }
|
8
9
|
let(:records) { User.all }
|
9
10
|
|
10
|
-
before
|
11
|
+
before do
|
11
12
|
create(:user, username: 'johndoe', email: 'johndoe@example.com')
|
12
13
|
create(:user, username: 'msmith', email: 'mary.smith@example.com')
|
13
14
|
end
|
@@ -31,7 +32,7 @@ describe AjaxDatatablesRails::ORM::ActiveRecord do
|
|
31
32
|
)
|
32
33
|
end
|
33
34
|
|
34
|
-
it '
|
35
|
+
it 'does not sort a column which is not orderable' do
|
35
36
|
datatable.params[:order]['0'] = { column: '0', dir: 'asc' }
|
36
37
|
datatable.params[:order]['1'] = { column: '4', dir: 'desc' }
|
37
38
|
|
@@ -46,30 +47,32 @@ describe AjaxDatatablesRails::ORM::ActiveRecord do
|
|
46
47
|
end
|
47
48
|
|
48
49
|
describe '#sort_records with nulls last using global config' do
|
49
|
-
before {
|
50
|
-
after {
|
51
|
-
|
50
|
+
before { datatable.nulls_last = true }
|
51
|
+
after { datatable.nulls_last = false }
|
52
|
+
|
52
53
|
it 'can handle multiple sorting columns' do
|
54
|
+
skip('unsupported database adapter') if ENV['DB_ADAPTER'] == 'oracle_enhanced'
|
55
|
+
|
53
56
|
# set to order by Users username in ascending order, and
|
54
57
|
# by Users email in descending order
|
55
58
|
datatable.params[:order]['0'] = { column: '0', dir: 'asc' }
|
56
59
|
datatable.params[:order]['1'] = { column: '1', dir: 'desc' }
|
57
60
|
expect(datatable.sort_records(records).to_sql).to include(
|
58
|
-
|
59
|
-
'CASE WHEN users.email IS NULL THEN 1 ELSE 0 END, users.email DESC'
|
61
|
+
"ORDER BY users.username ASC #{nulls_last_sql(datatable)}, users.email DESC #{nulls_last_sql(datatable)}"
|
60
62
|
)
|
61
63
|
end
|
62
64
|
end
|
63
|
-
|
65
|
+
|
64
66
|
describe '#sort_records with nulls last using column config' do
|
65
67
|
it 'can handle multiple sorting columns' do
|
68
|
+
skip('unsupported database adapter') if ENV['DB_ADAPTER'] == 'oracle_enhanced'
|
69
|
+
|
66
70
|
# set to order by Users username in ascending order, and
|
67
71
|
# by Users email in descending order
|
68
72
|
nulls_last_datatable.params[:order]['0'] = { column: '0', dir: 'asc' }
|
69
73
|
nulls_last_datatable.params[:order]['1'] = { column: '1', dir: 'desc' }
|
70
74
|
expect(nulls_last_datatable.sort_records(records).to_sql).to include(
|
71
|
-
|
72
|
-
'CASE WHEN users.email IS NULL THEN 1 ELSE 0 END, users.email DESC'
|
75
|
+
"ORDER BY users.username ASC, users.email DESC #{nulls_last_sql(datatable)}"
|
73
76
|
)
|
74
77
|
end
|
75
78
|
end
|
data/spec/factories/user.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
FactoryBot.define do
|
2
4
|
factory :user do |f|
|
3
5
|
f.username { Faker::Internet.user_name }
|
4
6
|
f.email { Faker::Internet.email }
|
5
7
|
f.first_name { Faker::Name.first_name }
|
6
8
|
f.last_name { Faker::Name.last_name }
|
7
|
-
f.post_id { (
|
9
|
+
f.post_id { (1..100).to_a.sample }
|
8
10
|
end
|
9
11
|
end
|
data/spec/install_oracle.sh
CHANGED
@@ -4,9 +4,15 @@ wget 'https://github.com/cbandy/travis-oracle/archive/v2.0.3.tar.gz'
|
|
4
4
|
mkdir -p ~/.travis/oracle
|
5
5
|
tar xz --strip-components 1 -C ~/.travis/oracle -f v2.0.3.tar.gz
|
6
6
|
|
7
|
-
|
7
|
+
if [ -n ${CUSTOM_ORACLE_FILE} ]; then
|
8
|
+
wget -q ${CUSTOM_ORACLE_FILE} -O ~/.travis/oracle/oracle-xe-11.2.0-1.0.x86_64.rpm.zip
|
9
|
+
else
|
10
|
+
~/.travis/oracle/download.sh
|
11
|
+
fi
|
12
|
+
|
8
13
|
~/.travis/oracle/install.sh
|
9
14
|
|
10
|
-
|
11
|
-
|
15
|
+
# in dev env: sqlplus system/password@localhost/XE
|
16
|
+
"${ORACLE_HOME}/bin/sqlplus" -L -S / AS SYSDBA <<SQL
|
17
|
+
ALTER USER ${USER} IDENTIFIED BY ${USER};
|
12
18
|
SQL
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'simplecov'
|
2
4
|
require 'rspec'
|
5
|
+
require 'rspec/retry'
|
3
6
|
require 'database_cleaner'
|
4
7
|
require 'factory_bot'
|
5
8
|
require 'faker'
|
@@ -21,13 +24,6 @@ RSpec.configure do |config|
|
|
21
24
|
FactoryBot.find_definitions
|
22
25
|
end
|
23
26
|
|
24
|
-
config.after(:each) do
|
25
|
-
AjaxDatatablesRails.configure do |c|
|
26
|
-
c.db_adapter = ActiveRecord::Base.connection.adapter_name.downcase.to_sym
|
27
|
-
c.orm = :active_record
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
27
|
config.color = true
|
32
28
|
config.fail_fast = false
|
33
29
|
|
@@ -42,45 +38,54 @@ RSpec.configure do |config|
|
|
42
38
|
DatabaseCleaner.clean_with(:truncation)
|
43
39
|
end
|
44
40
|
|
45
|
-
config.before
|
41
|
+
config.before do
|
46
42
|
DatabaseCleaner.strategy = :transaction
|
47
43
|
end
|
48
44
|
|
49
|
-
config.before
|
45
|
+
config.before do
|
50
46
|
DatabaseCleaner.start
|
51
47
|
end
|
52
48
|
|
53
|
-
config.after
|
49
|
+
config.after do
|
54
50
|
DatabaseCleaner.clean
|
55
51
|
end
|
56
|
-
end
|
57
52
|
|
58
|
-
|
53
|
+
# disable monkey patching
|
54
|
+
# see: https://relishapp.com/rspec/rspec-core/v/3-8/docs/configuration/zero-monkey-patching-mode
|
55
|
+
config.disable_monkey_patching!
|
59
56
|
|
57
|
+
if ENV.key?('GITHUB_ACTIONS')
|
58
|
+
config.around do |ex|
|
59
|
+
ex.run_with_retry retry: 3
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Configure ActiveRecord
|
60
65
|
adapter = ENV.fetch('DB_ADAPTER', 'postgresql')
|
61
66
|
|
62
67
|
options = {
|
63
68
|
adapter: adapter,
|
64
69
|
database: 'ajax_datatables_rails',
|
65
|
-
encoding: 'utf8'
|
70
|
+
encoding: 'utf8',
|
66
71
|
}
|
67
72
|
|
68
|
-
options =
|
69
|
-
|
70
|
-
|
73
|
+
options =
|
74
|
+
case adapter
|
75
|
+
when 'postgresql'
|
76
|
+
options.merge(host: '127.0.0.1', port: 5432, username: 'postgres', password: 'postgres')
|
77
|
+
when 'mysql2'
|
78
|
+
options.merge(host: '127.0.0.1', port: 3306, username: 'root', password: 'root')
|
79
|
+
when 'oracle_enhanced'
|
80
|
+
options.merge(host: '127.0.0.1/xe', username: ENV['USER'], password: ENV['USER'], database: 'xe')
|
81
|
+
when 'sqlite3'
|
82
|
+
options.merge(database: ':memory:')
|
83
|
+
end
|
71
84
|
|
72
85
|
ActiveRecord::Base.establish_connection(options)
|
73
86
|
|
74
|
-
|
75
|
-
|
76
|
-
c.orm = :active_record
|
77
|
-
end
|
87
|
+
# Require our gem
|
88
|
+
require 'ajax-datatables-rails'
|
78
89
|
|
79
|
-
|
80
|
-
|
81
|
-
load File.dirname(__FILE__) + '/support/datatable_cond_date.rb'
|
82
|
-
load File.dirname(__FILE__) + '/support/datatable_cond_numeric.rb'
|
83
|
-
load File.dirname(__FILE__) + '/support/datatable_cond_proc.rb'
|
84
|
-
load File.dirname(__FILE__) + '/support/datatable_cond_string.rb'
|
85
|
-
load File.dirname(__FILE__) + '/support/datatable_order_nulls_last.rb'
|
86
|
-
require File.dirname(__FILE__) + '/support/test_models.rb'
|
90
|
+
# Load test helpers
|
91
|
+
Dir[File.dirname(__FILE__) + '/support/**/*.rb'].sort.each { |f| require f }
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ComplexDatatable < AjaxDatatablesRails::ActiveRecord
|
4
|
+
def view_columns
|
5
|
+
@view_columns ||= {
|
6
|
+
username: { source: 'User.username' },
|
7
|
+
email: { source: 'User.email' },
|
8
|
+
first_name: { source: 'User.first_name' },
|
9
|
+
last_name: { source: 'User.last_name' },
|
10
|
+
post_id: { source: 'User.post_id', orderable: false },
|
11
|
+
created_at: { source: 'User.created_at' },
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def data
|
16
|
+
records.map do |record|
|
17
|
+
{
|
18
|
+
username: record.username,
|
19
|
+
email: record.email,
|
20
|
+
first_name: record.first_name,
|
21
|
+
last_name: record.last_name,
|
22
|
+
post_id: record.post_id,
|
23
|
+
created_at: record.created_at,
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_raw_records
|
29
|
+
User.all
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ComplexDatatableArray < ComplexDatatable
|
4
|
+
def data
|
5
|
+
records.map do |record|
|
6
|
+
[
|
7
|
+
record.username,
|
8
|
+
record.email,
|
9
|
+
record.first_name,
|
10
|
+
record.last_name,
|
11
|
+
record.post_id,
|
12
|
+
record.created_at,
|
13
|
+
]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class DatatableCondEq < ComplexDatatable
|
2
4
|
def view_columns
|
3
5
|
super.deep_merge(post_id: { cond: :eq })
|
@@ -42,7 +44,7 @@ end
|
|
42
44
|
|
43
45
|
class DatatableCondInWithRegex < DatatableCondIn
|
44
46
|
def view_columns
|
45
|
-
super.deep_merge(post_id: { cond: :in, use_regex: false, orderable: true,
|
47
|
+
super.deep_merge(post_id: { cond: :in, use_regex: false, orderable: true, formatter: ->(str) { cast_regex_value(str) } })
|
46
48
|
end
|
47
49
|
|
48
50
|
def cast_regex_value(value)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class DatatableCondStartWith < ComplexDatatable
|
2
4
|
def view_columns
|
3
5
|
super.deep_merge(first_name: { cond: :start_with })
|
@@ -22,6 +24,12 @@ class DatatableCondStringEq < ComplexDatatable
|
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
27
|
+
class DatatableCondStringIn < ComplexDatatable
|
28
|
+
def view_columns
|
29
|
+
super.deep_merge(email: { cond: :string_in, formatter: ->(o) { o.split('|') } })
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
25
33
|
class DatatableCondNullValue < ComplexDatatable
|
26
34
|
def view_columns
|
27
35
|
super.deep_merge(email: { cond: :null_value })
|
@@ -30,6 +38,6 @@ end
|
|
30
38
|
|
31
39
|
class DatatableWithFormater < ComplexDatatable
|
32
40
|
def view_columns
|
33
|
-
super.deep_merge(last_name: {
|
41
|
+
super.deep_merge(last_name: { formatter: ->(o) { o.upcase } })
|
34
42
|
end
|
35
43
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# rubocop:disable Metrics/MethodLength
|
2
4
|
def sample_params
|
3
5
|
ActionController::Parameters.new(
|
@@ -42,7 +44,7 @@ def sample_params
|
|
42
44
|
},
|
43
45
|
},
|
44
46
|
'order' => {
|
45
|
-
'0' => {'column' => '0', 'dir' => 'asc'}
|
47
|
+
'0' => { 'column' => '0', 'dir' => 'asc' },
|
46
48
|
},
|
47
49
|
'start' => '0', 'length' => '10', 'search' => {
|
48
50
|
'value' => '', 'regex' => 'false'
|
@@ -51,49 +53,22 @@ def sample_params
|
|
51
53
|
}
|
52
54
|
)
|
53
55
|
end
|
54
|
-
# rubocop:enable Metrics/MethodLength
|
55
|
-
|
56
|
-
class ComplexDatatable < AjaxDatatablesRails::Base
|
57
|
-
def view_columns
|
58
|
-
@view_columns ||= {
|
59
|
-
username: { source: 'User.username' },
|
60
|
-
email: { source: 'User.email' },
|
61
|
-
first_name: { source: 'User.first_name' },
|
62
|
-
last_name: { source: 'User.last_name' },
|
63
|
-
post_id: { source: 'User.post_id', orderable: false },
|
64
|
-
created_at: { source: 'User.created_at' },
|
65
|
-
}
|
66
|
-
end
|
67
56
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
first_name: record.first_name,
|
74
|
-
last_name: record.last_name,
|
75
|
-
post_id: record.post_id,
|
76
|
-
created_at: record.created_at,
|
77
|
-
}
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def get_raw_records
|
82
|
-
User.all
|
83
|
-
end
|
57
|
+
def sample_params_json
|
58
|
+
hash_params = sample_params.to_unsafe_h
|
59
|
+
hash_params['columns'] = hash_params['columns'].values
|
60
|
+
hash_params['order'] = hash_params['order'].values
|
61
|
+
ActionController::Parameters.new(hash_params)
|
84
62
|
end
|
63
|
+
# rubocop:enable Metrics/MethodLength
|
85
64
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
record.post_id,
|
95
|
-
record.created_at,
|
96
|
-
]
|
97
|
-
end
|
65
|
+
def nulls_last_sql(datatable)
|
66
|
+
case datatable.db_adapter
|
67
|
+
when :pg, :postgresql, :postgres, :oracle
|
68
|
+
'NULLS LAST'
|
69
|
+
when :mysql, :mysql2, :sqlite, :sqlite3
|
70
|
+
'IS NULL'
|
71
|
+
else
|
72
|
+
raise 'unsupported database adapter'
|
98
73
|
end
|
99
74
|
end
|