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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +120 -0
  3. data/.rubocop.yml +17 -7
  4. data/Appraisals +15 -20
  5. data/CHANGELOG.md +54 -1
  6. data/Gemfile +0 -5
  7. data/Guardfile +16 -0
  8. data/README.md +238 -112
  9. data/Rakefile +1 -0
  10. data/ajax-datatables-rails.gemspec +24 -20
  11. data/bin/_guard-core +29 -0
  12. data/bin/appraisal +29 -0
  13. data/bin/bundle +114 -0
  14. data/bin/guard +29 -0
  15. data/bin/rake +29 -0
  16. data/bin/rspec +29 -0
  17. data/bin/rubocop +29 -0
  18. data/doc/migrate.md +97 -0
  19. data/doc/webpack.md +7 -2
  20. data/gemfiles/{rails_5.2.0.gemfile → rails_5.2.4.gemfile} +3 -5
  21. data/gemfiles/{rails_5.0.7.gemfile → rails_6.0.3.gemfile} +4 -6
  22. data/gemfiles/{rails_5.1.6.gemfile → rails_6.1.0.gemfile} +4 -6
  23. data/lib/ajax-datatables-rails.rb +12 -1
  24. data/lib/ajax-datatables-rails/active_record.rb +7 -0
  25. data/lib/ajax-datatables-rails/base.rb +47 -46
  26. data/lib/ajax-datatables-rails/datatable.rb +6 -0
  27. data/lib/ajax-datatables-rails/datatable/column.rb +65 -20
  28. data/lib/ajax-datatables-rails/datatable/column/date_filter.rb +12 -21
  29. data/lib/ajax-datatables-rails/datatable/column/order.rb +1 -1
  30. data/lib/ajax-datatables-rails/datatable/column/search.rb +37 -22
  31. data/lib/ajax-datatables-rails/datatable/datatable.rb +16 -7
  32. data/lib/ajax-datatables-rails/datatable/simple_order.rb +23 -10
  33. data/lib/ajax-datatables-rails/datatable/simple_search.rb +2 -0
  34. data/lib/ajax-datatables-rails/error.rb +9 -0
  35. data/lib/ajax-datatables-rails/orm.rb +6 -0
  36. data/lib/ajax-datatables-rails/orm/active_record.rb +11 -12
  37. data/lib/ajax-datatables-rails/version.rb +13 -1
  38. data/lib/generators/rails/templates/datatable.rb +1 -1
  39. data/spec/ajax-datatables-rails/base_spec.rb +129 -93
  40. data/spec/ajax-datatables-rails/datatable/column_spec.rb +105 -37
  41. data/spec/ajax-datatables-rails/datatable/datatable_spec.rb +71 -31
  42. data/spec/ajax-datatables-rails/datatable/simple_order_spec.rb +36 -14
  43. data/spec/ajax-datatables-rails/datatable/simple_search_spec.rb +4 -2
  44. data/spec/ajax-datatables-rails/orm/active_record_filter_records_spec.rb +315 -272
  45. data/spec/ajax-datatables-rails/orm/active_record_paginate_records_spec.rb +9 -8
  46. data/spec/ajax-datatables-rails/orm/active_record_sort_records_spec.rb +17 -14
  47. data/spec/factories/user.rb +3 -1
  48. data/spec/install_oracle.sh +9 -3
  49. data/spec/spec_helper.rb +33 -28
  50. data/spec/support/datatables/complex_datatable.rb +31 -0
  51. data/spec/support/datatables/complex_datatable_array.rb +16 -0
  52. data/spec/support/{datatable_cond_date.rb → datatables/datatable_cond_date.rb} +2 -0
  53. data/spec/support/{datatable_cond_numeric.rb → datatables/datatable_cond_numeric.rb} +3 -1
  54. data/spec/support/{datatable_cond_proc.rb → datatables/datatable_cond_proc.rb} +2 -0
  55. data/spec/support/{datatable_cond_string.rb → datatables/datatable_cond_string.rb} +9 -1
  56. data/spec/support/datatables/datatable_cond_unknown.rb +7 -0
  57. data/spec/support/{datatable_order_nulls_last.rb → datatables/datatable_order_nulls_last.rb} +2 -0
  58. data/spec/support/{test_helpers.rb → helpers/params.rb} +17 -42
  59. data/spec/support/{test_models.rb → models/user.rb} +2 -0
  60. data/spec/support/schema.rb +3 -1
  61. metadata +76 -75
  62. data/.travis.yml +0 -80
  63. data/gemfiles/rails_4.0.13.gemfile +0 -14
  64. data/gemfiles/rails_4.1.16.gemfile +0 -14
  65. data/gemfiles/rails_4.2.10.gemfile +0 -14
  66. data/lib/ajax-datatables-rails/config.rb +0 -31
  67. data/lib/ajax_datatables_rails.rb +0 -15
  68. data/lib/generators/datatable/config_generator.rb +0 -19
  69. data/lib/generators/datatable/templates/ajax_datatables_rails_config.rb +0 -12
  70. data/spec/ajax-datatables-rails/configuration_spec.rb +0 -43
  71. data/spec/ajax-datatables-rails/extended_spec.rb +0 -20
  72. 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(:view) { double('view', params: sample_params) }
6
- let(:datatable) { ComplexDatatable.new(view) }
7
+ let(:datatable) { ComplexDatatable.new(sample_params) }
7
8
  let(:records) { User.all }
8
9
 
9
- before(:each) do
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 AjaxDatatablesRails.config.db_adapter.in? %i[oracle oracleenhanced]
21
- if Rails.version.in? %w[4.0.13 4.1.16 4.2.10]
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 AjaxDatatablesRails.config.db_adapter.in? %i[oracle oracleenhanced]
39
- if Rails.version.in? %w[4.0.13 4.1.16 4.2.10]
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(:view) { double('view', params: sample_params) }
6
- let(:datatable) { ComplexDatatable.new(view) }
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(:each) do
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 'should not sort a column which is not orderable' do
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 { AjaxDatatablesRails.config.nulls_last = true }
50
- after { AjaxDatatablesRails.config.nulls_last = false }
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
- 'ORDER BY CASE WHEN users.username IS NULL THEN 1 ELSE 0 END, users.username ASC, ' +
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
- 'ORDER BY users.username ASC, ' +
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
@@ -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 { ((1..100).to_a).sample }
9
+ f.post_id { (1..100).to_a.sample }
8
10
  end
9
11
  end
@@ -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
- ~/.travis/oracle/download.sh
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
- "$ORACLE_HOME/bin/sqlplus" -L -S / AS SYSDBA <<SQL
11
- ALTER USER $USER IDENTIFIED BY $USER;
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(:each) do
41
+ config.before do
46
42
  DatabaseCleaner.strategy = :transaction
47
43
  end
48
44
 
49
- config.before(:each) do
45
+ config.before do
50
46
  DatabaseCleaner.start
51
47
  end
52
48
 
53
- config.after(:each) do
49
+ config.after do
54
50
  DatabaseCleaner.clean
55
51
  end
56
- end
57
52
 
58
- require 'ajax-datatables-rails'
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 = options.merge(username: 'root') if adapter == 'mysql2'
69
- options = options.merge(username: ENV['USER'], password: ENV['USER'], database: 'xe', host: '127.0.0.1/xe') if adapter == 'oracle_enhanced'
70
- options = options.merge(database: ':memory:') if adapter == 'sqlite3'
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
- AjaxDatatablesRails.configure do |c|
75
- c.db_adapter = ActiveRecord::Base.connection.adapter_name.downcase.to_sym
76
- c.orm = :active_record
77
- end
87
+ # Require our gem
88
+ require 'ajax-datatables-rails'
78
89
 
79
- load File.dirname(__FILE__) + '/support/schema.rb'
80
- load File.dirname(__FILE__) + '/support/test_helpers.rb'
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 DatatableCondDate < ComplexDatatable
2
4
  def view_columns
3
5
  super.deep_merge(created_at: { cond: :date_range })
@@ -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, formater: ->(str) { cast_regex_value(str) } })
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 DatatableCondProc < ComplexDatatable
2
4
  def view_columns
3
5
  super.deep_merge(username: { cond: custom_filter })
@@ -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: { formater: -> (o) { o.upcase } })
41
+ super.deep_merge(last_name: { formatter: ->(o) { o.upcase } })
34
42
  end
35
43
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DatatableCondUnknown < ComplexDatatable
4
+ def view_columns
5
+ super.deep_merge(username: { cond: :foo })
6
+ end
7
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class DatatableOrderNullsLast < ComplexDatatable
2
4
  def view_columns
3
5
  super.deep_merge(email: { nulls_last: true })
@@ -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
- def data
69
- records.map do |record|
70
- {
71
- username: record.username,
72
- email: record.email,
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
- class ComplexDatatableArray < ComplexDatatable
87
- def data
88
- records.map do |record|
89
- [
90
- record.username,
91
- record.email,
92
- record.first_name,
93
- record.last_name,
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
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class User < ActiveRecord::Base
2
4
  end