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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32f4790c082cfaf7a15b4463d51e7bfd1d16ddb215ad132a40572765ff79e262
4
- data.tar.gz: cca488fce38bd4ea5dcba5112dca37fbc106c196010362ad1b2c24d231d0cf72
3
+ metadata.gz: c458882fe0c2ff86e0b262ccdc9e37af67c348941f902e29bee7a9ec7b1ad9f0
4
+ data.tar.gz: 9fe38de08324f1f281f5a7c24d3e0c782c71bc741a23ae301952c0ef7bfcbb09
5
5
  SHA512:
6
- metadata.gz: 3f50889d4584929e3a01f8895d7b3e10e8118dcfa7fe2a4188eefe38f2cdc4b3bf0b043f996a7c7d43ba7706f085dd3dddab84756f8e21d74e3f55f1a73ab083
7
- data.tar.gz: 7b36341f278d8cf407cd21060635b37723c14f7b564e510bf5699e6665d81b8fd282220d5fe031ad97f8b67224ce3ab0dddd4131ff18287ff3576d34df1af74d
6
+ metadata.gz: 943655268357523c6594845e708f41fbe515284736b1c96d6150514b6c39478d563719c4051c0c3568942e138c1166ab2193cec5585742c1640242a7adbdd381
7
+ data.tar.gz: 6507a0827be528e61dfb07f905b4016d0d65543b19b3becf8d557884890fa88dbdefd815441f0b6f4cc4c784b24ebb58924f0b69357576295138af67cdf7ca78
@@ -0,0 +1,120 @@
1
+ ---
2
+ name: CI
3
+
4
+ on:
5
+ - push
6
+ - pull_request
7
+
8
+ jobs:
9
+ rspec:
10
+ runs-on: ubuntu-20.04
11
+
12
+ env:
13
+ ORACLE_COOKIE: sqldev
14
+ ORACLE_FILE: oracle11g/xe/oracle-xe-11.2.0-1.0.x86_64.rpm.zip
15
+ ORACLE_HOME: /u01/app/oracle/product/11.2.0/xe
16
+ ORACLE_SID: XE
17
+
18
+ services:
19
+ postgres:
20
+ image: 'postgres:13'
21
+ ports: ['5432:5432']
22
+ env:
23
+ POSTGRES_PASSWORD: postgres
24
+ POSTGRES_DB: ajax_datatables_rails
25
+ options: >-
26
+ --health-cmd pg_isready
27
+ --health-interval 10s
28
+ --health-timeout 5s
29
+ --health-retries 5
30
+
31
+ # Using docker image fails with
32
+ # invalid reference format
33
+ # mariadb:
34
+ # image: 'mariadb:10.3'
35
+ # ports: ['3306:3306']
36
+ # env:
37
+ # MYSQL_ROOT_PASSWORD: root
38
+ # MYSQL_DATABASE: ajax_datatables_rails
39
+ # options: >-
40
+ # --health-cmd 'mysqladmin ping'
41
+ # --health-interval 10s
42
+ # --health-timeout 5s
43
+ # --health-retries 3
44
+
45
+ strategy:
46
+ fail-fast: false
47
+ matrix:
48
+ ruby:
49
+ - '3.0'
50
+ - '2.7'
51
+ - '2.6'
52
+ - '2.5'
53
+ rails:
54
+ - rails_5.2.4
55
+ - rails_6.0.3
56
+ - rails_6.1.0
57
+ adapter:
58
+ - sqlite3
59
+ - postgresql
60
+ - mysql2
61
+ - oracle_enhanced
62
+ exclude:
63
+ - ruby: '3.0'
64
+ rails: rails_5.2.4
65
+
66
+ steps:
67
+ - name: Checkout
68
+ uses: actions/checkout@v2
69
+
70
+ - name: Setup Ruby
71
+ uses: ruby/setup-ruby@v1
72
+ with:
73
+ ruby-version: ${{ matrix.ruby }}
74
+
75
+ - name: Set DB Adapter
76
+ env:
77
+ RAILS_VERSION: ${{ matrix.rails }}
78
+ DB_ADAPTER: ${{ matrix.adapter }}
79
+ CUSTOM_ORACLE_FILE: ${{ secrets.CUSTOM_ORACLE_FILE }}
80
+
81
+ # See: https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md#mysql
82
+ run: |
83
+ if [ "${DB_ADAPTER}" = "mysql2" ]; then
84
+ sudo systemctl start mysql.service
85
+ mysql -u root -proot -e 'create database ajax_datatables_rails;'
86
+ fi
87
+
88
+ if [ "${DB_ADAPTER}" = "oracle_enhanced" ]; then
89
+ ./spec/install_oracle.sh
90
+ # Fix error : libnnz11.so: cannot open shared object file: No such file or directory
91
+ sudo ln -s ${ORACLE_HOME}/lib/libnnz11.so /usr/lib/libnnz11.so
92
+ fi
93
+
94
+ - name: Setup Ruby cache
95
+ uses: actions/cache@v2
96
+ with:
97
+ path: vendor/bundle
98
+ key: ${{ runner.os }}-gems-${{ matrix.ruby }}-${{ matrix.rails }}-${{ matrix.adapter }}-${{ hashFiles('**/Gemfile.lock') }}
99
+ restore-keys: |
100
+ ${{ runner.os }}-gems-${{ matrix.ruby }}-${{ matrix.rails }}-${{ matrix.adapter }}-
101
+
102
+ - name: Bundle
103
+ env:
104
+ RAILS_VERSION: ${{ matrix.rails }}
105
+ DB_ADAPTER: ${{ matrix.adapter }}
106
+ BUNDLE_GEMFILE: gemfiles/${{ matrix.rails }}.gemfile
107
+ run: |
108
+ gem install bundler
109
+ bundle config path vendor/bundle
110
+ bundle install --jobs 4 --retry 3
111
+
112
+ - name: RSpec & publish code coverage
113
+ uses: paambaati/codeclimate-action@v2.7.5
114
+ env:
115
+ RAILS_VERSION: ${{ matrix.rails }}
116
+ DB_ADAPTER: ${{ matrix.adapter }}
117
+ BUNDLE_GEMFILE: gemfiles/${{ matrix.rails }}.gemfile
118
+ CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
119
+ with:
120
+ coverageCommand: bin/rake
data/.rubocop.yml CHANGED
@@ -1,14 +1,17 @@
1
1
  AllCops:
2
+ NewCops: enable
3
+ SuggestExtensions: false
2
4
  TargetRubyVersion: 2.5
3
5
  Exclude:
4
- - spec/**/*.rb
5
- - lib/ajax-datatables-rails.rb
6
- - lib/generators/rails/templates/*.rb
6
+ - bin/*
7
+ - lib/generators/**/*.rb
8
+ - gemfiles/*
9
+ - spec/**/*
7
10
 
8
- Documentation:
11
+ Style/Documentation:
9
12
  Enabled: false
10
13
 
11
- Gemspec/OrderedDependencies:
14
+ Layout/HashAlignment:
12
15
  Enabled: false
13
16
 
14
17
  Layout/EmptyLines:
@@ -44,5 +47,12 @@ Metrics/ClassLength:
44
47
  Naming/AccessorMethodName:
45
48
  Enabled: false
46
49
 
47
- Style/NumericPredicate:
48
- Enabled: false
50
+ Naming/FileName:
51
+ Exclude:
52
+ - lib/ajax-datatables-rails.rb
53
+
54
+ Style/TrailingCommaInArrayLiteral:
55
+ EnforcedStyleForMultiline: comma
56
+
57
+ Style/TrailingCommaInHashLiteral:
58
+ EnforcedStyleForMultiline: comma
data/Appraisals CHANGED
@@ -1,29 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RAILS_VERSIONS = {
4
- '4.0.13' => {
5
- 'mysql2' => '~> 0.3.18',
6
- 'activerecord-oracle_enhanced-adapter' => '~> 1.5.0'
7
- },
8
- '4.1.16' => {
9
- 'mysql2' => '~> 0.3.18',
10
- 'activerecord-oracle_enhanced-adapter' => '~> 1.5.0'
11
- },
12
- '4.2.10' => {
13
- 'activerecord-oracle_enhanced-adapter' => '~> 1.6.0'
4
+ '5.2.4' => {
5
+ 'activerecord-oracle_enhanced-adapter' => '~> 5.2.0',
6
+ 'sqlite3' => '~> 1.3.0',
7
+ 'mysql2' => '',
8
+ 'ruby-oci8' => '',
14
9
  },
15
- '5.0.7' => {
16
- 'activerecord-oracle_enhanced-adapter' => '~> 1.7.0',
17
- 'ruby-oci8' => ''
10
+ '6.0.3' => {
11
+ 'activerecord-oracle_enhanced-adapter' => '~> 6.0.0',
12
+ 'sqlite3' => '~> 1.4.0',
13
+ 'mysql2' => '',
14
+ 'ruby-oci8' => '',
18
15
  },
19
- '5.1.6' => {
20
- 'activerecord-oracle_enhanced-adapter' => '~> 1.8.0',
21
- 'ruby-oci8' => ''
16
+ '6.1.0' => {
17
+ 'activerecord-oracle_enhanced-adapter' => '~> 6.1.0',
18
+ 'sqlite3' => '~> 1.4.0',
19
+ 'mysql2' => '',
20
+ 'ruby-oci8' => '',
22
21
  },
23
- '5.2.0' => {
24
- 'activerecord-oracle_enhanced-adapter' => '~> 5.2.0',
25
- 'ruby-oci8' => ''
26
- }
27
22
  }.freeze
28
23
 
29
24
  RAILS_VERSIONS.each do |version, gems|
data/CHANGELOG.md CHANGED
@@ -1,12 +1,65 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.3.1 (2021-02-09)
4
+
5
+ * Fix rare case error `uninitialized constant AjaxDatatablesRails::ActiveRecord::Base` (merge: [#379](https://github.com/jbox-web/ajax-datatables-rails/pull/379))
6
+
7
+ ## 1.3.0 (2021-01-04)
8
+
9
+ * Drop support of Rails 5.0.x and 5.1.x
10
+ * Drop support of Ruby 2.4
11
+ * Add support of Rails 6.1
12
+ * Add support of Ruby 3.0
13
+ * Switch from Travis to Github Actions
14
+ * Improve specs
15
+ * Fix lib loading with JRuby (fixes [#371](https://github.com/jbox-web/ajax-datatables-rails/issues/371))
16
+ * Raise an error when column's `cond:` setting is unknown
17
+ * Make global search and column search work together (merge: [#350](https://github.com/jbox-web/ajax-datatables-rails/pull/350), fixes: [#258](https://github.com/jbox-web/ajax-datatables-rails/issues/258))
18
+ * Fix: date_range doesn't support searching by a date greater than today (merge: [#351](https://github.com/jbox-web/ajax-datatables-rails/pull/351))
19
+ * Fix: undefined method `fetch' for nil:NilClass (fix: [#307](https://github.com/jbox-web/ajax-datatables-rails/issues/307))
20
+ * Add support for json params (merge: [#355](https://github.com/jbox-web/ajax-datatables-rails/pull/355))
21
+
22
+ * `AjaxDatatablesRails.config` is removed with no replacement. The gem is now configless :)
23
+ * `AjaxDatatablesRails.config.db_adapter=` is removed and is configured per datatable class now. It defaults to Rails DB adapter. (fixes [#364](https://github.com/jbox-web/ajax-datatables-rails/issues/364))
24
+ * `AjaxDatatablesRails.config.nulls_last=` is removed and is configured per datatable class now (or by column). It defaults to false.
25
+
26
+ To mitigate this 3 changes see the [migration doc](/doc/migrate.md).
27
+
28
+ ## 1.2.0 (2020-04-19)
29
+
30
+ * Drop support of Rails 4.x
31
+ * Drop support of Ruby 2.3
32
+ * Use [zeitwerk](https://github.com/fxn/zeitwerk) to load gem files
33
+ * Add binstubs to ease development
34
+
35
+ This is the last version to support Rails 5.0.x, Rails 5.1.x and Ruby 2.4.x.
36
+
37
+ ## 1.1.0 (2019-12-12)
38
+
39
+ * Add rudimentary support for Microsoft SQL Server
40
+ * Fixes errors when options[param] is nil [PR 315](https://github.com/jbox-web/ajax-datatables-rails/pull/315) (thanks @allard)
41
+ * Improve query performance when nulls_last option is enabled [PR 317](https://github.com/jbox-web/ajax-datatables-rails/pull/317) (thanks @natebird)
42
+ * Add :string_in cond [PR 323](https://github.com/jbox-web/ajax-datatables-rails/pull/323) (thanks @donnguyen)
43
+ * Rename `sanitize` private method [PR 326](https://github.com/jbox-web/ajax-datatables-rails/pull/326) (thanks @epipheus)
44
+ * Update documentation
45
+ * Test with latest Rails (6.x) and Ruby versions (2.6)
46
+
47
+ This is the last version to support Rails 4.x and Ruby 2.3.x.
48
+
49
+ ## 1.0.0 (2018-08-28)
50
+
51
+ * Breaking change: Remove dependency on view_context [Issue #288](https://github.com/jbox-web/ajax-datatables-rails/issues/288)
52
+ * Breaking change: Replace `config.orm = :active_record` by a class : `AjaxDatatablesRails::ActiveRecord` [Fix #228](https://github.com/jbox-web/ajax-datatables-rails/issues/228)
53
+
54
+ To mitigate this 2 changes see the [migration doc](/doc/migrate.md).
55
+
3
56
  ## 0.4.3 (2018-06-05)
4
57
 
5
58
  * Add: Add `:string_eq` condition on columns filter [Issue #291](https://github.com/jbox-web/ajax-datatables-rails/issues/291)
6
59
 
7
60
  **Note :** This is the last version to support Rails 4.0.x and Rails 4.1.x
8
61
 
9
- ## 0.4.2 (2018-05-11)
62
+ ## 0.4.2 (2018-05-15)
10
63
 
11
64
  * Fix: Integer out of range [PR #289](https://github.com/jbox-web/ajax-datatables-rails/pull/289) from [PR #284](https://github.com/jbox-web/ajax-datatables-rails/pull/284)
12
65
 
data/Gemfile CHANGED
@@ -3,8 +3,3 @@
3
3
  source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
-
7
- # CodeClimate Test Coverage
8
- group :test do
9
- gem 'codeclimate-test-reporter', '~> 1.0.0'
10
- end
data/Guardfile ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ guard :rspec, cmd: 'bundle exec rspec' do
4
+ require 'guard/rspec/dsl'
5
+ dsl = Guard::RSpec::Dsl.new(self)
6
+
7
+ # RSpec files
8
+ rspec = dsl.rspec
9
+ watch(rspec.spec_helper) { rspec.spec_dir }
10
+ watch(rspec.spec_support) { rspec.spec_dir }
11
+ watch(rspec.spec_files)
12
+
13
+ # Ruby files
14
+ ruby = dsl.ruby
15
+ dsl.watch_spec_files_for(ruby.lib_files)
16
+ end
data/README.md CHANGED
@@ -3,21 +3,20 @@
3
3
  [![GitHub license](https://img.shields.io/github/license/jbox-web/ajax-datatables-rails.svg)](https://github.com/jbox-web/ajax-datatables-rails/blob/master/LICENSE)
4
4
  [![Gem](https://img.shields.io/gem/v/ajax-datatables-rails.svg)](https://rubygems.org/gems/ajax-datatables-rails)
5
5
  [![Gem](https://img.shields.io/gem/dtv/ajax-datatables-rails.svg)](https://rubygems.org/gems/ajax-datatables-rails)
6
- [![Build Status](https://travis-ci.org/jbox-web/ajax-datatables-rails.svg?branch=master)](https://travis-ci.org/jbox-web/ajax-datatables-rails)
6
+ [![CI](https://github.com/jbox-web/ajax-datatables-rails/workflows/CI/badge.svg)](https://github.com/jbox-web/ajax-datatables-rails/actions)
7
7
  [![Code Climate](https://codeclimate.com/github/jbox-web/ajax-datatables-rails/badges/gpa.svg)](https://codeclimate.com/github/jbox-web/ajax-datatables-rails)
8
8
  [![Test Coverage](https://codeclimate.com/github/jbox-web/ajax-datatables-rails/badges/coverage.svg)](https://codeclimate.com/github/jbox-web/ajax-datatables-rails/coverage)
9
- [![Dependency Status](https://gemnasium.com/jbox-web/ajax-datatables-rails.svg)](https://gemnasium.com/jbox-web/ajax-datatables-rails)
10
9
 
11
10
  **Important : This gem is targeted at DataTables version 1.10.x.**
12
11
 
13
12
  It's tested against :
14
13
 
15
- * Rails 4.0.13 / 4.1.16 / 4.2.10 / 5.0.7 / 5.1.6 / 5.2.0
16
- * Ruby 2.2.10 / 2.3.7 / 2.4.4 / 2.5.1
17
- * Postgresql 9.6
18
- * MySQL 5.6
19
- * Oracle XE 11.2 (thanks to [travis-oracle](https://github.com/cbandy/travis-oracle))
14
+ * Rails 5.2.4 / 6.0.3 / 6.1.0
15
+ * Ruby 2.5.x / 2.6.x / 2.7.x
20
16
  * SQLite3
17
+ * Postgresql 13
18
+ * MySQL 8
19
+ * Oracle XE 11.2 (thanks to [travis-oracle](https://github.com/cbandy/travis-oracle))
21
20
 
22
21
  ## Description
23
22
 
@@ -39,22 +38,9 @@ The final goal of this gem is to **generate a JSON** content that will be given
39
38
  All the datatable customizations (header, tr, td, css classes, width, height, buttons, etc...) **must** take place in the [javascript definition](#5-wire-up-the-javascript) of the datatable.
40
39
  jQuery DataTables is a very powerful tool with a lot of customizations available. Take the time to [read the doc](https://datatables.net/reference/option/).
41
40
 
41
+ You'll find a sample project here : https://ajax-datatables-rails.herokuapp.com
42
42
 
43
- ## Warning
44
-
45
- **Breaking changes :** the *v0.4* version is a **major break** from *v0.3*.
46
-
47
- The core has been rewriten to remove dependency on [Kaminari](https://github.com/kaminari/kaminari) or [WillPaginate](https://github.com/mislav/will_paginate).
48
-
49
- It also brings a new (more natural) way of defining columns, based on hash definitions (and not arrays) and add some filtering options for column search.
50
-
51
- [See below](#3-customize-the-generated-datatables-class) for more infos.
52
-
53
- To migrate on the v0.4 you'll need to :
54
-
55
- * update your DataTables classes to remove all the `extend` directives
56
- * switch to hash definitions of `view_columns`
57
- * update your views to declare your columns bindings ([See here](#5-wire-up-the-javascript))
43
+ Its real world examples. The code is here : https://github.com/jbox-web/ajax-datatables-rails-sample-project
58
44
 
59
45
 
60
46
  ## Installation
@@ -75,39 +61,12 @@ We assume here that you have already installed [jQuery DataTables](https://datat
75
61
 
76
62
  You can install jQuery DataTables :
77
63
 
78
- * with the [`jquery-datatables-rails`](https://github.com/rweng/jquery-datatables-rails) gem (which is a bit outdated)
64
+ * with the [`jquery-datatables`](https://github.com/mkhairi/jquery-datatables) gem
79
65
  * by adding the assets manually (in `vendor/assets`)
80
66
  * with [Rails webpacker gem](https://github.com/rails/webpacker) (see [here](/doc/webpack.md) for more infos)
81
67
 
82
68
 
83
- ## Configuration
84
-
85
- Generate the `ajax-datatables-rails` config file with this command :
86
-
87
- ```sh
88
- $ bundle exec rails generate datatable:config
89
- ```
90
-
91
- Doing so, will create the `config/initializers/ajax_datatables_rails.rb` file with the following content :
92
-
93
- ```ruby
94
- AjaxDatatablesRails.configure do |config|
95
- # available options for db_adapter are: :pg, :mysql, :mysql2, :sqlite, :sqlite3
96
- # config.db_adapter = :pg
97
-
98
- # Or you can use your rails environment adapter if you want a generic dev and production
99
- # config.db_adapter = Rails.configuration.database_configuration[Rails.env]['adapter'].to_sym
100
-
101
- # available options for orm are: :active_record, :mongoid
102
- # config.orm = :active_record
103
- end
104
- ```
105
-
106
- Uncomment the `config.db_adapter` line and set the corresponding value to your database and gem. This is all you need.
107
-
108
- Uncomment the `config.orm` line to set `active_record or mongoid` if included in your project. It defaults to `active_record`.
109
-
110
- #### Note
69
+ ## Note
111
70
 
112
71
  Currently `AjaxDatatablesRails` only supports `ActiveRecord` as ORM for performing database queries.
113
72
 
@@ -119,7 +78,7 @@ If you'd be interested in contributing to speed development, please [open an iss
119
78
  ## Quick start (in 5 steps)
120
79
 
121
80
  The following examples assume that we are setting up `ajax-datatables-rails` for an index page of users from a `User` model,
122
- and that we are using Postgresql as our db, because you **should be using it**. (It also works with other DB, see above, just be sure to have [configured the right adapter](#configuration))
81
+ and that we are using Postgresql as our db, because you **should be using it**. (It also works with other DB, [see above](#change-the-db-adapter-for-a-datatable-class))
123
82
 
124
83
  The goal is to render a users table and display : `id`, `first name`, `last name`, `email`, and `bio` for each user.
125
84
 
@@ -194,7 +153,7 @@ def view_columns
194
153
  @view_columns ||= {
195
154
  id: { source: "User.id" },
196
155
  first_name: { source: "User.first_name", cond: :like, searchable: true, orderable: true },
197
- last_name: { source: "User.last_name", cond: :like },
156
+ last_name: { source: "User.last_name", cond: :like, nulls_last: true },
198
157
  email: { source: "User.email" },
199
158
  bio: { source: "User.bio" },
200
159
  }
@@ -205,14 +164,40 @@ end
205
164
 
206
165
  `cond` can be :
207
166
 
208
- * `:like`, `:start_with`, `:end_with`, `:string_eq` for string or full text search
167
+ * `:like`, `:start_with`, `:end_with`, `:string_eq`, `:string_in` for string or full text search
209
168
  * `:eq`, `:not_eq`, `:lt`, `:gt`, `:lteq`, `:gteq`, `:in` for numeric
210
- * `:date_range` for date range (only for Rails > 4.2.x, see [here](#daterange-search))
169
+ * `:date_range` for date range
211
170
  * `:null_value` for nil field
212
- * `Proc` for whatever (see [here](https://github.com/ajahongir/ajax-datatables-rails-v-0-4-0-how-to/blob/master/app/datatables/city_datatable.rb) for real example)
171
+ * `Proc` for whatever (see [here](https://github.com/jbox-web/ajax-datatables-rails-sample-project/blob/master/app/datatables/city_datatable.rb) for real example)
172
+
173
+ The `nulls_last` param allows for nulls to be ordered last. You can configure it by column, like above, or by datatable class :
174
+
175
+ ```ruby
176
+ class MyDatatable < AjaxDatatablesRails::ActiveRecord
177
+ self.nulls_last = true
178
+
179
+ # ... other methods (view_columns, data...)
180
+ end
181
+ ```
213
182
 
214
183
  See [here](#columns-syntax) to get more details about columns definitions and how to play with associated models.
215
184
 
185
+ You can customize or sanitize the search value passed to the DB by using the `:formatter` option with a lambda :
186
+
187
+ ```ruby
188
+ def view_columns
189
+ @view_columns ||= {
190
+ id: { source: "User.id" },
191
+ first_name: { source: "User.first_name" },
192
+ last_name: { source: "User.last_name" },
193
+ email: { source: "User.email", formatter: -> (o) { o.upcase } },
194
+ bio: { source: "User.bio" },
195
+ }
196
+ end
197
+ ```
198
+
199
+ The object passed to the lambda is the search value.
200
+
216
201
  #### b. Map data
217
202
 
218
203
  Then we need to map the records retrieved by the `get_raw_records` method to the real values we want to display :
@@ -226,12 +211,13 @@ def data
226
211
  last_name: record.last_name,
227
212
  email: record.email,
228
213
  bio: record.bio,
229
- DT_RowId: record.id, # This will set the id attribute on the corresponding <tr> in the datatable
214
+ DT_RowId: record.id, # This will automagically set the id attribute on the corresponding <tr> in the datatable
230
215
  }
231
216
  end
232
217
  end
233
218
  ```
234
- You can either use the v0.3 Array style for your columns :
219
+
220
+ **Deprecated:** You can either use the v0.3 Array style for your columns :
235
221
 
236
222
  This method builds a 2d array that is used by datatables to construct the html
237
223
  table. Insert the values you want on each column.
@@ -291,7 +277,7 @@ def additional_data
291
277
  end
292
278
  ```
293
279
 
294
- Very useful with https://github.com/vedmack/yadcf to provide values for dropdown filters.
280
+ Very useful with [datatables-factory](https://github.com/jbox-web/datatables-factory) (or [yadcf](https://github.com/vedmack/yadcf)) to provide values for dropdown filters.
295
281
 
296
282
 
297
283
  ### 4) Setup the Controller action
@@ -302,7 +288,7 @@ Set the controller to respond to JSON
302
288
  def index
303
289
  respond_to do |format|
304
290
  format.html
305
- format.json { render json: UserDatatable.new(view_context) }
291
+ format.json { render json: UserDatatable.new(params) }
306
292
  end
307
293
  end
308
294
  ```
@@ -311,6 +297,8 @@ Don't forget to make sure the proper route has been added to `config/routes.rb`.
311
297
 
312
298
  [See here](#pass-options-to-the-datatable-class) if you need to inject params in the `UserDatatable`.
313
299
 
300
+ **Note :** If you have more than **2** datatables in your application, don't forget to read [this](#use-http-post-method-medium).
301
+
314
302
  ### 5) Wire up the Javascript
315
303
 
316
304
  Finally, the javascript to tie this all together. In the appropriate `coffee` file:
@@ -322,7 +310,8 @@ $ ->
322
310
  $('#users-datatable').dataTable
323
311
  processing: true
324
312
  serverSide: true
325
- ajax: $('#users-datatable').data('source')
313
+ ajax:
314
+ url: $('#users-datatable').data('source')
326
315
  pagingType: 'full_numbers'
327
316
  columns: [
328
317
  {data: 'id'}
@@ -345,7 +334,9 @@ jQuery(document).ready(function() {
345
334
  $('#users-datatable').dataTable({
346
335
  "processing": true,
347
336
  "serverSide": true,
348
- "ajax": $('#users-datatable').data('source'),
337
+ "ajax": {
338
+ "url": $('#users-datatable').data('source')
339
+ },
349
340
  "pagingType": "full_numbers",
350
341
  "columns": [
351
342
  {"data": "id"},
@@ -371,7 +362,9 @@ Sometimes you'll need to use view helper methods like `link_to`, `mail_to`,
371
362
  To have these methods available to be used, this is the way to go:
372
363
 
373
364
  ```ruby
374
- class MyCustomDatatable < AjaxDatatablesRails::Base
365
+ class UserDatatable < AjaxDatatablesRails::ActiveRecord
366
+ extend Forwardable
367
+
375
368
  # either define them one-by-one
376
369
  def_delegator :@view, :check_box_tag
377
370
  def_delegator :@view, :link_to
@@ -383,6 +376,11 @@ class MyCustomDatatable < AjaxDatatablesRails::Base
383
376
 
384
377
  # ... other methods (view_columns, get_raw_records...)
385
378
 
379
+ def initialize(params, opts = {})
380
+ @view = opts[:view_context]
381
+ super
382
+ end
383
+
386
384
  # now, you'll have these methods available to be used anywhere
387
385
  def data
388
386
  records.map do |record|
@@ -397,15 +395,29 @@ class MyCustomDatatable < AjaxDatatablesRails::Base
397
395
  end
398
396
  end
399
397
  end
398
+
399
+ # and in your controller:
400
+ def index
401
+ respond_to do |format|
402
+ format.html
403
+ format.json { render json: UserDatatable.new(params, view_context: view_context) }
404
+ end
405
+ end
400
406
  ```
401
407
 
408
+ ### Using view decorators
409
+
402
410
  If you want to keep things tidy in the data mapping method, you could use
403
411
  [Draper](https://github.com/drapergem/draper) to define column mappings like below.
404
412
 
413
+ **Note :** This is the recommanded way as you don't need to inject the `view_context` in the Datatable object to access helpers methods.
414
+ It also helps in separating view/presentation logic from filtering logic (the only one that really matters in a datatable class).
415
+
405
416
  Example :
406
417
 
407
418
  ```ruby
408
- ...
419
+ class UserDatatable < AjaxDatatablesRails::ActiveRecord
420
+ ...
409
421
  def data
410
422
  records.map do |record|
411
423
  {
@@ -418,7 +430,8 @@ Example :
418
430
  }
419
431
  end
420
432
  end
421
- ...
433
+ ...
434
+ end
422
435
 
423
436
  class UserDecorator < ApplicationDecorator
424
437
  delegate :last_name, :bio
@@ -447,16 +460,9 @@ class UserDecorator < ApplicationDecorator
447
460
  end
448
461
  ```
449
462
 
450
- **Note :** On the long term it's much more cleaner than using `def_delegator` since decorators are reusable everywhere in your application :)
451
-
452
- So we **strongly recommand you to use Draper decorators.** It will help keeping your DataTables class small and clean and keep focused on what they should do (mostly) : filtering records ;)
453
-
454
- **Note 2 :** The `def_delegator` might disappear in a near future : [#288 [RFC] Remove dependency on view_context](https://github.com/jbox-web/ajax-datatables-rails/issues/288).
455
- You're invited to give your opinion :)
456
-
457
463
  ### Pass options to the datatable class
458
464
 
459
- An `AjaxDatatablesRails::Base` inherited class can accept an options hash at initialization. This provides room for flexibility when required.
465
+ An `AjaxDatatablesRails::ActiveRecord` inherited class can accept an options hash at initialization. This provides room for flexibility when required.
460
466
 
461
467
  Example:
462
468
 
@@ -465,12 +471,12 @@ Example:
465
471
  def index
466
472
  respond_to do |format|
467
473
  format.html
468
- format.json { render json: UserDatatable.new(view_context, user: current_user, from: 1.month.ago) }
474
+ format.json { render json: UserDatatable.new(params, user: current_user, from: 1.month.ago) }
469
475
  end
470
476
  end
471
477
 
472
478
  # The datatable class
473
- class UnrespondedMessagesDatatable < AjaxDatatablesRails::Base
479
+ class UnrespondedMessagesDatatable < AjaxDatatablesRails::ActiveRecord
474
480
 
475
481
  # ... other methods (view_columns, data...)
476
482
 
@@ -495,6 +501,24 @@ class UnrespondedMessagesDatatable < AjaxDatatablesRails::Base
495
501
  end
496
502
  ```
497
503
 
504
+ ### Change the DB adapter for a datatable class
505
+
506
+ If you have models from different databases you can set the `db_adapter` on the datatable class :
507
+
508
+ ```ruby
509
+ class MySharedModelDatatable < AjaxDatatablesRails::ActiveRecord
510
+ self.db_adapter = :oracle_enhanced
511
+
512
+ # ... other methods (view_columns, data...)
513
+
514
+ def get_raw_records
515
+ AnimalsRecord.connected_to(role: :reading) do
516
+ Dog.all
517
+ end
518
+ end
519
+ end
520
+ ```
521
+
498
522
  ### Columns syntax
499
523
 
500
524
  You can mix several model in the same datatable.
@@ -508,13 +532,13 @@ available in our datatable to search and sort by.
508
532
 
509
533
  def view_columns
510
534
  @view_columns ||= {
511
- first_name: 'User.first_name',
512
- last_name: 'User.last_name',
513
- order_number: 'PurchaseOrder.number',
514
- order_created_at: 'PurchaseOrder.created_at',
515
- quantity: 'Purchase::LineItem.quantity',
516
- unit_price: 'Purchase::LineItem.unit_price',
517
- item_total: 'Purchase::LineItem.item_total'
535
+ first_name: { source: 'User.first_name' },
536
+ last_name: { source: 'User.last_name' },
537
+ order_number: { source: 'PurchaseOrder.number' },
538
+ order_created_at: { source: 'PurchaseOrder.created_at' },
539
+ quantity: { source: 'Purchase::LineItem.quantity' },
540
+ unit_price: { source: 'Purchase::LineItem.unit_price' },
541
+ item_total: { source: 'Purchase::LineItem.item_total }'
518
542
  }
519
543
  end
520
544
  ```
@@ -546,14 +570,14 @@ The related definition would be :
546
570
  ```ruby
547
571
  def view_columns
548
572
  @view_columns ||= {
549
- course_type: 'CourseType.name',
550
- course_name: 'Course.name',
551
- contact_name: 'Contact.full_name',
552
- competency_type: 'CompetencyType.name',
553
- event_title: 'Event.title',
554
- event_start: 'Event.event_start',
555
- event_end: 'Event.event_end',
556
- event_status: 'Event.status',
573
+ course_type: { source: 'CourseType.name' },
574
+ course_name: { source: 'Course.name' },
575
+ contact_name: { source: 'Contact.full_name' },
576
+ competency_type: { source: 'CompetencyType.name' },
577
+ event_title: { source: 'Event.title' },
578
+ event_start: { source: 'Event.event_start' },
579
+ event_end: { source: 'Event.event_end' },
580
+ event_status: { source: 'Event.status' },
557
581
  }
558
582
  end
559
583
 
@@ -610,18 +634,18 @@ See [DefaultScope is evil](https://rails-bestpractices.com/posts/2013/06/15/defa
610
634
 
611
635
  ### DateRange search
612
636
 
613
- This feature works with [yadcf](https://github.com/vedmack/yadcf).
637
+ This feature works with [datatables-factory](https://github.com/jbox-web/datatables-factory) (or [yadcf](https://github.com/vedmack/yadcf)).
614
638
 
615
639
  To enable the date range search, for example `created_at` :
616
640
 
617
- * add a 'created_at' `<th>` in your html
641
+ * add a `created_at` `<th>` in your html
618
642
  * declare your column in `view_columns` : `created_at: { source: 'Post.created_at', cond: :date_range, delimiter: '-yadcf_delim-' }`
619
643
  * add it in `data` : `created_at: record.decorate.created_at`
620
644
  * setup yadcf to make `created_at` search field a range
621
645
 
622
646
  ### Generator Syntax
623
647
 
624
- Also, a class that inherits from `AjaxDatatablesRails::Base` is not tied to an
648
+ Also, a class that inherits from `AjaxDatatablesRails::ActiveRecord` is not tied to an
625
649
  existing model, module, constant or any type of class in your Rails app.
626
650
  You can pass a name to your datatable class like this:
627
651
 
@@ -641,7 +665,123 @@ In the end, it's up to the developer which model(s), scope(s), relationship(s)
641
665
  (or else) to employ inside the datatable class to retrieve records from the
642
666
  database.
643
667
 
644
- ### Creating indices for Postgresql
668
+ ## Tests
669
+
670
+ Datatables can be tested with Capybara provided you don't use Webrick during integration tests.
671
+
672
+ Long story short and as a rule of thumb : use the same webserver everywhere (dev, prod, staging, test, etc...).
673
+
674
+ If you use Puma (the Rails default webserver), use Puma everywhere, even in CI/test environment. The same goes for Thin.
675
+
676
+ You will avoid the usual story : it works in dev but not in test environment...
677
+
678
+ If you want to test datatables with a lot of data you might need this kind of tricks : https://robots.thoughtbot.com/automatically-wait-for-ajax-with-capybara. (thanks CharlieIGG)
679
+
680
+ ## ProTips™
681
+
682
+ ### Create a master parent class (Easy)
683
+
684
+ In the same spirit of Rails `ApplicationController` and `ApplicationRecord`, you can create an `ApplicationDatatable` class (in `app/datatables/application_datatable.rb`)
685
+ that will be inherited from other classes :
686
+
687
+ ```ruby
688
+ class ApplicationDatatable < AjaxDatatablesRails::ActiveRecord
689
+ # puts commonly used methods here
690
+ end
691
+
692
+ class PostDatatable < ApplicationDatatable
693
+ end
694
+ ```
695
+
696
+ This way it will be easier to DRY you datatables.
697
+
698
+ ### Speedup JSON rendering (Easy)
699
+
700
+ Install [yajl-ruby](https://github.com/brianmario/yajl-ruby), basically :
701
+
702
+ ```ruby
703
+ gem 'yajl-ruby', require: 'yajl'
704
+ ```
705
+
706
+ then
707
+
708
+ ```sh
709
+ $ bundle install
710
+ ```
711
+
712
+ That's all :) ([Automatically prefer Yajl or JSON backend over Yaml, if available](https://github.com/rails/rails/commit/63bb955a99eb46e257655c93dd64e86ebbf05651))
713
+
714
+ ### Use HTTP `POST` method (Medium)
715
+
716
+ Use HTTP `POST` method to avoid `414 Request-URI Too Large` error. See : [#278](https://github.com/jbox-web/ajax-datatables-rails/issues/278) and [#308](https://github.com/jbox-web/ajax-datatables-rails/issues/308#issuecomment-424897335).
717
+
718
+ You can easily define a route concern in `config/routes.rb` and reuse it when you need it :
719
+
720
+ ```ruby
721
+ Rails.application.routes.draw do
722
+ concern :with_datatable do
723
+ post 'datatable', on: :collection
724
+ end
725
+
726
+ resources :posts, concerns: [:with_datatable]
727
+ resources :users, concerns: [:with_datatable]
728
+ end
729
+ ```
730
+
731
+ then in your controllers :
732
+
733
+ ```ruby
734
+ # PostsController
735
+ def index
736
+ end
737
+
738
+ def datatable
739
+ render json: PostDatatable.new(params)
740
+ end
741
+
742
+ # UsersController
743
+ def index
744
+ end
745
+
746
+ def datatable
747
+ render json: UserDatatable.new(params)
748
+ end
749
+ ```
750
+
751
+ then in your views :
752
+
753
+ ```html
754
+ # posts/index.html.erb
755
+ <table id="posts-datatable" data-source="<%= datatable_posts_path(format: :json) %>">
756
+
757
+ # users/index.html.erb
758
+ <table id="users-datatable" data-source="<%= datatable_users_path(format: :json) %>">
759
+ ```
760
+
761
+ then in your Coffee/JS :
762
+
763
+ ```coffee
764
+ # send params in form data
765
+ $ ->
766
+ $('#posts-datatable').dataTable
767
+ ajax:
768
+ url: $('#posts-datatable').data('source')
769
+ type: 'POST'
770
+ # ...others options, see [here](#5-wire-up-the-javascript)
771
+
772
+ # send params as json data
773
+ $ ->
774
+ $('#users-datatable').dataTable
775
+ ajax:
776
+ url: $('#users-datatable').data('source')
777
+ contentType: 'application/json'
778
+ type: 'POST'
779
+ data: (d) ->
780
+ JSON.stringify d
781
+ # ...others options, see [here](#5-wire-up-the-javascript)
782
+ ```
783
+
784
+ ### Create indices for Postgresql (Expert)
645
785
 
646
786
  In order to speed up the `ILIKE` queries that are executed when using the default configuration, you might want to consider adding some indices.
647
787
  For postgresql, you are advised to use the [gin/gist index type](http://www.postgresql.org/docs/current/interactive/pgtrgm.html).
@@ -668,27 +808,13 @@ def change
668
808
  end
669
809
  ```
670
810
 
671
- ### Speedup JSON rendering
672
-
673
- Install [yajl-ruby](https://github.com/brianmario/yajl-ruby), basically :
674
-
675
- ```ruby
676
- gem 'yajl-ruby', require: 'yajl'
677
- ```
678
-
679
- then
680
-
681
- ```sh
682
- $ bundle install
683
- ```
684
-
685
- That's all :) ([Automatically prefer Yajl or JSON backend over Yaml, if available](https://github.com/rails/rails/commit/63bb955a99eb46e257655c93dd64e86ebbf05651))
686
-
687
811
  ## Tutorial
688
812
 
689
- You'll find a sample project [here](https://github.com/ajahongir/ajax-datatables-rails-v-0-4-0-how-to). Its real world example.
813
+ Filtering by JSONB column values : [#277](https://github.com/jbox-web/ajax-datatables-rails/issues/277#issuecomment-366526373)
814
+
815
+ Use [has_scope](https://github.com/plataformatec/has_scope) gem with `ajax-datatables-rails` : [#280](https://github.com/jbox-web/ajax-datatables-rails/issues/280)
690
816
 
691
- Filtering by JSONB column values : [#277](https://github.com/jbox-web/ajax-datatables-rails/issues/277)
817
+ Use [Datatable orthogonal data](https://datatables.net/manual/data/orthogonal-data) : see [#269](https://github.com/jbox-web/ajax-datatables-rails/issues/269#issuecomment-387940478)
692
818
 
693
819
  ## Contributing
694
820