ajax-datatables-rails 0.4.3 → 1.3.1

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