ajax-datatables-rails 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +26 -0
- data/.gitignore +20 -0
- data/.rspec +1 -0
- data/.rubocop.yml +1157 -0
- data/.travis.yml +68 -0
- data/Appraisals +34 -0
- data/Gemfile +5 -1
- data/LICENSE +17 -18
- data/README.md +239 -239
- data/Rakefile +1 -1
- data/ajax-datatables-rails.gemspec +31 -24
- data/gemfiles/rails_4.0.13.gemfile +14 -0
- data/gemfiles/rails_4.1.15.gemfile +14 -0
- data/gemfiles/rails_4.2.8.gemfile +13 -0
- data/gemfiles/rails_5.0.3.gemfile +13 -0
- data/gemfiles/rails_5.1.1.gemfile +13 -0
- data/lib/ajax-datatables-rails.rb +9 -8
- data/lib/ajax-datatables-rails/base.rb +80 -156
- data/lib/ajax-datatables-rails/config.rb +8 -5
- data/lib/ajax-datatables-rails/datatable/column.rb +169 -0
- data/lib/ajax-datatables-rails/datatable/column_date_filter.rb +41 -0
- data/lib/ajax-datatables-rails/datatable/datatable.rb +79 -0
- data/lib/ajax-datatables-rails/datatable/simple_order.rb +31 -0
- data/lib/ajax-datatables-rails/datatable/simple_search.rb +18 -0
- data/lib/ajax-datatables-rails/orm/active_record.rb +52 -0
- data/lib/ajax-datatables-rails/version.rb +1 -1
- data/lib/generators/datatable/templates/ajax_datatables_rails_config.rb +3 -3
- data/lib/generators/rails/datatable_generator.rb +7 -19
- data/lib/generators/rails/templates/datatable.rb +26 -14
- data/spec/ajax-datatables-rails/base_spec.rb +190 -0
- data/spec/ajax-datatables-rails/configuration_spec.rb +43 -0
- data/spec/ajax-datatables-rails/datatable/column_spec.rb +109 -0
- data/spec/ajax-datatables-rails/datatable/datatable_spec.rb +87 -0
- data/spec/ajax-datatables-rails/datatable/simple_order_spec.rb +13 -0
- data/spec/ajax-datatables-rails/datatable/simple_search_spec.rb +17 -0
- data/spec/ajax-datatables-rails/extended_spec.rb +20 -0
- data/spec/ajax-datatables-rails/orm/active_record_filter_records_spec.rb +439 -0
- data/spec/ajax-datatables-rails/orm/active_record_paginate_records_spec.rb +66 -0
- data/spec/ajax-datatables-rails/orm/active_record_sort_records_spec.rb +34 -0
- data/spec/ajax-datatables-rails/orm/active_record_spec.rb +25 -0
- data/spec/factories/user.rb +9 -0
- data/spec/install_oracle.sh +12 -0
- data/spec/spec_helper.rb +75 -3
- data/spec/support/schema.rb +14 -0
- data/spec/support/test_helpers.rb +174 -0
- data/spec/support/test_models.rb +2 -0
- metadata +169 -37
- data/lib/ajax-datatables-rails/extensions/kaminari.rb +0 -12
- data/lib/ajax-datatables-rails/extensions/simple_paginator.rb +0 -12
- data/lib/ajax-datatables-rails/extensions/will_paginate.rb +0 -12
- data/lib/ajax-datatables-rails/models.rb +0 -6
- data/spec/ajax-datatables-rails/ajax_datatables_rails_spec.rb +0 -351
- data/spec/ajax-datatables-rails/kaminari_spec.rb +0 -35
- data/spec/ajax-datatables-rails/models_spec.rb +0 -10
- data/spec/ajax-datatables-rails/simple_paginator_spec.rb +0 -32
- data/spec/ajax-datatables-rails/will_paginate_spec.rb +0 -28
- data/spec/schema.rb +0 -35
- data/spec/test_models.rb +0 -21
data/.travis.yml
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
dist: trusty
|
2
|
+
language: ruby
|
3
|
+
sudo: required
|
4
|
+
cache: bundler
|
5
|
+
rvm:
|
6
|
+
- 2.2.7
|
7
|
+
- 2.3.4
|
8
|
+
gemfile:
|
9
|
+
- gemfiles/rails_4.0.13.gemfile
|
10
|
+
- gemfiles/rails_4.1.15.gemfile
|
11
|
+
- gemfiles/rails_4.2.8.gemfile
|
12
|
+
- gemfiles/rails_5.0.3.gemfile
|
13
|
+
- gemfiles/rails_5.1.1.gemfile
|
14
|
+
matrix:
|
15
|
+
include:
|
16
|
+
- rvm: 2.4.1
|
17
|
+
gemfile: gemfiles/rails_4.2.8.gemfile
|
18
|
+
env: DB_ADAPTER=postgresql
|
19
|
+
- rvm: 2.4.1
|
20
|
+
gemfile: gemfiles/rails_5.0.3.gemfile
|
21
|
+
env: DB_ADAPTER=postgresql
|
22
|
+
- rvm: 2.4.1
|
23
|
+
gemfile: gemfiles/rails_5.1.1.gemfile
|
24
|
+
env: DB_ADAPTER=postgresql
|
25
|
+
- rvm: 2.4.1
|
26
|
+
gemfile: gemfiles/rails_4.2.8.gemfile
|
27
|
+
env: DB_ADAPTER=mysql2
|
28
|
+
- rvm: 2.4.1
|
29
|
+
gemfile: gemfiles/rails_5.0.3.gemfile
|
30
|
+
env: DB_ADAPTER=mysql2
|
31
|
+
- rvm: 2.4.1
|
32
|
+
gemfile: gemfiles/rails_5.1.1.gemfile
|
33
|
+
env: DB_ADAPTER=mysql2
|
34
|
+
- rvm: 2.4.1
|
35
|
+
gemfile: gemfiles/rails_4.2.8.gemfile
|
36
|
+
env: DB_ADAPTER=oracle_enhanced
|
37
|
+
- rvm: 2.4.1
|
38
|
+
gemfile: gemfiles/rails_5.0.3.gemfile
|
39
|
+
env: DB_ADAPTER=oracle_enhanced
|
40
|
+
- rvm: 2.4.1
|
41
|
+
gemfile: gemfiles/rails_5.1.1.gemfile
|
42
|
+
env: DB_ADAPTER=oracle_enhanced
|
43
|
+
after_success:
|
44
|
+
- bundle exec codeclimate-test-reporter
|
45
|
+
services:
|
46
|
+
- postgresql
|
47
|
+
- mysql
|
48
|
+
addons:
|
49
|
+
postgresql: '9.6'
|
50
|
+
apt:
|
51
|
+
packages:
|
52
|
+
- mysql-server-5.6
|
53
|
+
- mysql-client-core-5.6
|
54
|
+
- mysql-client-5.6
|
55
|
+
before_install:
|
56
|
+
- sh -c "if [ '$DB_ADAPTER' = 'mysql2' ]; then mysql -e 'create database ajax_datatables_rails;'; fi"
|
57
|
+
- sh -c "if [ '$DB_ADAPTER' = 'postgresql' ]; then psql -c 'create database ajax_datatables_rails;' -U postgres; fi"
|
58
|
+
- sh -c "if [ '$DB_ADAPTER' = 'oracle_enhanced' ]; then ./spec/install_oracle.sh; fi"
|
59
|
+
env:
|
60
|
+
global:
|
61
|
+
- ORACLE_COOKIE=sqldev
|
62
|
+
- ORACLE_FILE=oracle11g/xe/oracle-xe-11.2.0-1.0.x86_64.rpm.zip
|
63
|
+
- ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe
|
64
|
+
- ORACLE_SID=XE
|
65
|
+
matrix:
|
66
|
+
- DB_ADAPTER=postgresql
|
67
|
+
- DB_ADAPTER=mysql2
|
68
|
+
- DB_ADAPTER=oracle_enhanced
|
data/Appraisals
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
RAILS_VERSIONS = {
|
2
|
+
'4.0.13' => {
|
3
|
+
'mysql2' => '~> 0.3.18',
|
4
|
+
'activerecord-oracle_enhanced-adapter' => '~> 1.5.0'
|
5
|
+
},
|
6
|
+
'4.1.15' => {
|
7
|
+
'mysql2' => '~> 0.3.18',
|
8
|
+
'activerecord-oracle_enhanced-adapter' => '~> 1.5.0'
|
9
|
+
},
|
10
|
+
'4.2.8' => {
|
11
|
+
'activerecord-oracle_enhanced-adapter' => '~> 1.6.0'
|
12
|
+
},
|
13
|
+
'5.0.3' => {
|
14
|
+
'activerecord-oracle_enhanced-adapter' => '~> 1.7.0',
|
15
|
+
'ruby-oci8' => ''
|
16
|
+
},
|
17
|
+
'5.1.1' => {
|
18
|
+
'activerecord-oracle_enhanced-adapter' => '~> 1.8.0',
|
19
|
+
'ruby-oci8' => ''
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
RAILS_VERSIONS.each do |version, gems|
|
24
|
+
appraise "rails_#{version}" do
|
25
|
+
gem 'rails', version
|
26
|
+
gems.each do |name, version|
|
27
|
+
if version.empty?
|
28
|
+
gem name
|
29
|
+
else
|
30
|
+
gem name, version
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/Gemfile
CHANGED
data/LICENSE
CHANGED
@@ -1,22 +1,21 @@
|
|
1
|
-
|
1
|
+
The MIT License (MIT)
|
2
2
|
|
3
|
-
|
3
|
+
Copyright (c) 2012 Joel Quenneville
|
4
4
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
the following conditions:
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
12
11
|
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
15
14
|
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
OF
|
22
|
-
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,28 +1,23 @@
|
|
1
1
|
# ajax-datatables-rails
|
2
2
|
|
3
|
-
[![
|
4
|
-
[![Gem
|
5
|
-
[![
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
[
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
```
|
22
|
-
|
23
|
-
If you have dataTables 1.10 in your project, then use the gem's latest version,
|
24
|
-
or point to the `master` branch.
|
25
|
-
|
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
|
+
[![Gem](https://img.shields.io/gem/v/ajax-datatables-rails.svg)](https://rubygems.org/gems/ajax-datatables-rails)
|
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)
|
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
|
+
[![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
|
+
|
11
|
+
> __Important__
|
12
|
+
>
|
13
|
+
> This gem is targeted at Datatables version 1.10.x.
|
14
|
+
>
|
15
|
+
> It's tested against :
|
16
|
+
> * Rails 4.0.13 / 4.1.15 / 4.2.8 / 5.0.2 / 5.1.0
|
17
|
+
> * Ruby 2.2.7 / 2.3.4 / 2.4.1
|
18
|
+
> * Postgresql
|
19
|
+
> * MySQL
|
20
|
+
> * Oracle XE 11.2 (thanks to [travis-oracle](https://github.com/cbandy/travis-oracle))
|
26
21
|
|
27
22
|
## Description
|
28
23
|
|
@@ -52,12 +47,16 @@ and get in touch.
|
|
52
47
|
|
53
48
|
Add these lines to your application's Gemfile:
|
54
49
|
|
55
|
-
|
56
|
-
|
50
|
+
```ruby
|
51
|
+
gem 'jquery-datatables-rails'
|
52
|
+
gem 'ajax-datatables-rails'
|
53
|
+
```
|
57
54
|
|
58
55
|
And then execute:
|
59
56
|
|
60
|
-
|
57
|
+
```sh
|
58
|
+
$ bundle
|
59
|
+
```
|
61
60
|
|
62
61
|
The `jquery-datatables-rails` gem is listed as a convenience, to ease adding
|
63
62
|
jQuery dataTables to your Rails project. You can always add the plugin assets
|
@@ -65,142 +64,160 @@ manually via the assets pipeline. If you decide to use the
|
|
65
64
|
`jquery-datatables-rails` gem, please refer to its installation instructions
|
66
65
|
[here](https://github.com/rweng/jquery-datatables-rails).
|
67
66
|
|
68
|
-
|
67
|
+
|
68
|
+
## Usage
|
69
|
+
|
69
70
|
*The following examples assume that we are setting up ajax-datatables-rails for
|
70
|
-
an index of users from a `User` model, and that we are using postgresql as
|
71
|
+
an index page of users from a `User` model, and that we are using postgresql as
|
71
72
|
our db, because you __should be using it__, if not, please refer to the
|
72
73
|
[Searching on non text-based columns](#searching-on-non-text-based-columns)
|
73
74
|
entry in the Additional Notes section.*
|
74
75
|
|
76
|
+
|
75
77
|
### Generate
|
76
|
-
Run the following command:
|
77
78
|
|
78
|
-
|
79
|
+
Run the following command:
|
79
80
|
|
81
|
+
```sh
|
82
|
+
$ rails generate datatable User
|
83
|
+
```
|
80
84
|
|
81
85
|
This will generate a file named `user_datatable.rb` in `app/datatables`.
|
82
86
|
Open the file and customize in the functions as directed by the comments.
|
83
87
|
|
84
88
|
Take a look [here](#generator-syntax) for an explanation about the generator syntax.
|
85
89
|
|
86
|
-
|
90
|
+
|
91
|
+
### Build the View
|
92
|
+
|
93
|
+
You should always start by the single source of truth, which is your html view. Suppose we need to render a users table and display: first name, last name, and bio for each user.
|
94
|
+
|
95
|
+
Something like this:
|
96
|
+
|
97
|
+
|First Name|Last Name|Brief Bio|
|
98
|
+
|----------|---------|---------|
|
99
|
+
|John |Doe |Is your default user everywhere|
|
100
|
+
|Jane |Doe |Is John's wife|
|
101
|
+
|James |Doe |Is John's brother and best friend|
|
102
|
+
|
103
|
+
|
104
|
+
* Set up an html `<table>` with a `<thead>` and `<tbody>`
|
105
|
+
* Add in your table headers if desired
|
106
|
+
* Don't add any rows to the body of the table, datatables does this automatically
|
107
|
+
* Add a data attribute to the `<table>` tag with the url of the JSON feed, in our case is the `users_path` as we're pointing to the `UsersController#index` action
|
108
|
+
|
109
|
+
|
110
|
+
```html
|
111
|
+
<table id="users-table", data-source="<%= users_path(format: :json) %>">
|
112
|
+
<thead>
|
113
|
+
<tr>
|
114
|
+
<th>First Name</th>
|
115
|
+
<th>Last Name</th>
|
116
|
+
<th>Brief Bio</th>
|
117
|
+
</tr>
|
118
|
+
</thead>
|
119
|
+
<tbody>
|
120
|
+
</tbody>
|
121
|
+
</table>
|
122
|
+
```
|
123
|
+
|
124
|
+
|
125
|
+
### Customize the generated Datatables class
|
126
|
+
|
87
127
|
```ruby
|
88
|
-
def
|
128
|
+
def view_columns
|
89
129
|
# Declare strings in this format: ModelName.column_name
|
90
|
-
|
130
|
+
# or in aliased_join_table.column_name format
|
131
|
+
@view_columns ||= {}
|
91
132
|
end
|
133
|
+
```
|
92
134
|
|
93
|
-
|
94
|
-
|
95
|
-
|
135
|
+
* In this method, add a list of the model(s) columns mapped to the data you need to present. In this case: `first_name`, `last_name` and `bio`.
|
136
|
+
|
137
|
+
This gives us:
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
def view_columns
|
141
|
+
@view_columns ||= {
|
142
|
+
first_name: { source: "User.first_name", cond: :like, searchable: true, orderable: true },
|
143
|
+
last_name: { source: "User.last_name", cond: :like },
|
144
|
+
bio: { source: "User.bio" },
|
145
|
+
}
|
96
146
|
end
|
97
147
|
```
|
98
148
|
|
99
|
-
|
100
|
-
correspond to the columns in our view table. For example
|
101
|
-
`[users.f_name, users.l_name, users.bio]`. This array is used for sorting by
|
102
|
-
various columns. The sequence of these 3 columns must mirror the order of
|
103
|
-
declarations in the `data` method below. You cannot leave this array empty as of
|
104
|
-
0.3.0.
|
149
|
+
**Notes :** by default `orderable` and `searchable` are true and `cond` is `:like`.
|
105
150
|
|
106
|
-
|
107
|
-
want searchable by datatables. Suppose we need to sort and search users
|
108
|
-
`:first_name`, `last_name` and `bio`.
|
151
|
+
`cond` can be :
|
109
152
|
|
110
|
-
|
153
|
+
* `:like`, `:start_with`, `:end_with` for string or full text search
|
154
|
+
* `:eq`, `:not_eq`, `:lt`, `:gt`, `:lteq`, `:gteq`, `:in` for numeric
|
155
|
+
* `:date_range` for date range (only for Rails > 4.2.x)
|
156
|
+
* `:null_value` for nil field
|
157
|
+
* `Proc` for whatever
|
111
158
|
|
112
|
-
|
113
|
-
|
159
|
+
[See here](#searching-on-non-text-based-columns) for notes about the `view_columns` settings (if using something different from `postgres`).
|
160
|
+
[Read these notes](#columns-syntax) about considerations for the `view_columns` method.
|
114
161
|
|
115
|
-
def sortable_columns
|
116
|
-
@sortable_columns ||= %w(User.first_name User.last_name User.bio)
|
117
|
-
# this is equal to:
|
118
|
-
# @sortable_columns ||= ['User.first_name', 'User.last_name', 'User.bio']
|
119
|
-
end
|
120
162
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
163
|
+
#### Map data
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
def data
|
167
|
+
records.map do |record|
|
168
|
+
{
|
169
|
+
# a hash of key value pairs
|
170
|
+
}
|
171
|
+
end
|
125
172
|
end
|
126
173
|
```
|
127
174
|
|
128
|
-
* [See here](#searching-on-non-text-based-columns) for notes about the
|
129
|
-
`searchable_columns` settings (if using something different from `postgre`).
|
130
|
-
* [Read these notes](#searchable-and-sortable-columns-syntax) about
|
131
|
-
considerations for the `searchable_columns` and `sortable_columns` methods.
|
132
|
-
|
133
|
-
### Map data
|
134
175
|
```ruby
|
135
176
|
def data
|
136
177
|
records.map do |record|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
178
|
+
{
|
179
|
+
first_name: record.first_name,
|
180
|
+
last_name: record.last_name,
|
181
|
+
bio: record.bio,
|
182
|
+
# 'DT_RowId' => record.id, # This will set the id attribute on the corresponding <tr> in the datatable
|
183
|
+
}
|
141
184
|
end
|
142
185
|
end
|
143
186
|
```
|
144
187
|
|
145
|
-
|
146
|
-
table. Insert the values you want on each column.
|
188
|
+
You can either use the v0.3 Array style for your columns :
|
147
189
|
|
148
190
|
```ruby
|
149
191
|
def data
|
150
192
|
records.map do |record|
|
151
193
|
[
|
152
|
-
|
153
|
-
record.last_name
|
154
|
-
record.bio
|
194
|
+
# comma separated list of the values for each cell of a table row
|
195
|
+
# example: record.first_name, record.last_name
|
155
196
|
]
|
156
197
|
end
|
157
198
|
end
|
158
199
|
```
|
159
200
|
|
160
|
-
|
161
|
-
|
162
|
-
column must be a sortable column. For more, see
|
163
|
-
[this issue](https://github.com/antillas21/ajax-datatables-rails/issues/83).
|
164
|
-
|
165
|
-
[See here](#using-view-helpers) if you need to use view helpers in the
|
166
|
-
returned 2D array, like `link_to`, `mail_to`, `resource_path`, etc.
|
167
|
-
|
168
|
-
#### Automatic addition of ID
|
169
|
-
If you want the gem inserts automatically the ID of the record in the `<tr>` element
|
170
|
-
as shown in this [DataTable axample](http://www.datatables.net/examples/server_side/ids.html),
|
171
|
-
you have to perform some modifications in both `some_datatable.rb` file and in your javascript.
|
201
|
+
This method builds a 2d array that is used by datatables to construct the html
|
202
|
+
table. Insert the values you want on each column.
|
172
203
|
|
173
|
-
Here is an example:
|
174
204
|
```ruby
|
175
205
|
def data
|
176
206
|
records.map do |record|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
}
|
207
|
+
[
|
208
|
+
record.first_name,
|
209
|
+
record.last_name,
|
210
|
+
record.bio
|
211
|
+
]
|
183
212
|
end
|
184
213
|
end
|
185
214
|
```
|
186
215
|
|
187
|
-
|
188
|
-
|
189
|
-
$(function() {
|
190
|
-
return $('#table_id').dataTable({
|
191
|
-
processing: true,
|
192
|
-
serverSide: true,
|
193
|
-
ajax: 'ajax_url',
|
194
|
-
columns: [
|
195
|
-
{data: '0' },
|
196
|
-
{data: '1' },
|
197
|
-
{data: '2' }
|
198
|
-
]
|
199
|
-
});
|
200
|
-
});
|
201
|
-
```
|
216
|
+
[See here](#using-view-helpers) if you need to use view helpers like `link_to`, `mail_to`, `resource_path`, etc.
|
217
|
+
|
202
218
|
|
203
219
|
#### Get Raw Records
|
220
|
+
|
204
221
|
```ruby
|
205
222
|
def get_raw_records
|
206
223
|
# insert query here
|
@@ -219,15 +236,27 @@ def get_raw_records
|
|
219
236
|
end
|
220
237
|
```
|
221
238
|
|
222
|
-
Obviously, you can construct your query as required for the use case the
|
223
|
-
|
239
|
+
Obviously, you can construct your query as required for the use case the datatable is used.
|
240
|
+
|
241
|
+
Example:
|
242
|
+
|
243
|
+
```ruby
|
244
|
+
def get_raw_records
|
245
|
+
User.active.with_recent_messages
|
246
|
+
end
|
247
|
+
```
|
248
|
+
|
249
|
+
You can put any logic in `get_raw_records` [based on any parameters you inject](#options) in the `Datatable` object.
|
250
|
+
|
251
|
+
> __IMPORTANT:__ Make sure to return an `ActiveRecord::Relation` object
|
252
|
+
> as the end product of this method.
|
253
|
+
>
|
254
|
+
> Why? Because the result from this method, will be chained (for now)
|
255
|
+
> to `ActiveRecord` methods for sorting, filtering and pagination.
|
224
256
|
|
225
|
-
__IMPORTANT:__ Make sure to return an `ActiveRecord::Relation` object as the
|
226
|
-
end product of this method. Why? Because the result from this method, will
|
227
|
-
be chained (for now) to `ActiveRecord` methods for sorting, filtering
|
228
|
-
and pagination.
|
229
257
|
|
230
258
|
#### Associated and nested models
|
259
|
+
|
231
260
|
The previous example has only one single model. But what about if you have
|
232
261
|
some associated nested models and in a report you want to show fields from
|
233
262
|
these tables.
|
@@ -237,71 +266,52 @@ Contact, Competency and CompetencyType` models. We want to have a datatables
|
|
237
266
|
report which has the following column:
|
238
267
|
|
239
268
|
```ruby
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
269
|
+
'coursetypes.name',
|
270
|
+
'courses.name',
|
271
|
+
'events.title',
|
272
|
+
'events.event_start',
|
273
|
+
'events.event_end',
|
274
|
+
'contacts.full_name',
|
275
|
+
'competency_types.name',
|
276
|
+
'events.status'
|
248
277
|
```
|
249
278
|
|
250
279
|
We want to sort and search on all columns of the list. The related definition
|
251
280
|
would be:
|
252
281
|
|
253
282
|
```ruby
|
283
|
+
def view_columns
|
284
|
+
@view_columns ||= [
|
285
|
+
'Coursetype.name',
|
286
|
+
'Course.name',
|
287
|
+
'Event.title',
|
288
|
+
'Event.event_start',
|
289
|
+
'Event.event_end',
|
290
|
+
'Contact.last_name',
|
291
|
+
'CompetencyType.name',
|
292
|
+
'Event.status'
|
293
|
+
]
|
294
|
+
end
|
254
295
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
'CompetencyType.name',
|
264
|
-
'Event.status'
|
265
|
-
]
|
266
|
-
end
|
267
|
-
|
268
|
-
def searchable_columns
|
269
|
-
@searchable_columns ||= [
|
270
|
-
'Coursetype.name',
|
271
|
-
'Course.name',
|
272
|
-
'Event.title',
|
273
|
-
'Event.event_start',
|
274
|
-
'Event.event_end',
|
275
|
-
'Contact.last_name',
|
276
|
-
'CompetencyType.name',
|
277
|
-
'Event.status'
|
278
|
-
]
|
279
|
-
end
|
280
|
-
|
281
|
-
def get_raw_records
|
282
|
-
Event.joins(
|
283
|
-
{ course: :coursetype },
|
284
|
-
{ allocations: {
|
285
|
-
teacher: [:contact, {competencies: :competency_type}]
|
286
|
-
}
|
287
|
-
}).distinct
|
288
|
-
end
|
296
|
+
def get_raw_records
|
297
|
+
Event.joins(
|
298
|
+
{ course: :coursetype },
|
299
|
+
{ allocations: {
|
300
|
+
teacher: [:contact, {competencies: :competency_type}]
|
301
|
+
}
|
302
|
+
}).distinct
|
303
|
+
end
|
289
304
|
```
|
290
305
|
|
291
306
|
__Some comments for the above code:__
|
292
307
|
|
293
|
-
1. In the
|
294
|
-
`searchable_columns` we use `last_name` from the `Contact` model. The reason
|
295
|
-
is we can use only database columns as sort or search fields and the full_name
|
296
|
-
is not a database field.
|
297
|
-
|
298
|
-
2. In the `get_raw_records` method we have quite a complex query having one to
|
308
|
+
1. In the `get_raw_records` method we have quite a complex query having one to
|
299
309
|
many and may to many associations using the joins ActiveRecord method.
|
300
310
|
The joins will generate INNER JOIN relations in the SQL query. In this case,
|
301
311
|
we do not include all event in the report if we have events which is not
|
302
312
|
associated with any model record from the relation.
|
303
313
|
|
304
|
-
|
314
|
+
2. To have all event records in the list we should use the `.includes` method,
|
305
315
|
which generate LEFT OUTER JOIN relation of the SQL query.
|
306
316
|
__IMPORTANT:__ Make sure to append `.references(:related_model)` with any
|
307
317
|
associated model. That forces the eager loading of all the associated models
|
@@ -317,23 +327,36 @@ is not empty.
|
|
317
327
|
So the query using the `.includes()` method is:
|
318
328
|
|
319
329
|
```ruby
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
}
|
330
|
+
def get_raw_records
|
331
|
+
Event.includes(
|
332
|
+
{ course: :coursetype },
|
333
|
+
{ allocations: {
|
334
|
+
teacher: [:contact, { competencies: :competency_type }]
|
326
335
|
}
|
327
|
-
|
328
|
-
|
336
|
+
}
|
337
|
+
).references(:course).distinct
|
338
|
+
end
|
339
|
+
```
|
340
|
+
|
341
|
+
|
342
|
+
#### Additional datas
|
343
|
+
|
344
|
+
You can inject other key/value pairs in the rendered JSON by defining the `#additional_datas` method :
|
345
|
+
|
346
|
+
```ruby
|
347
|
+
def additional_datas
|
348
|
+
{
|
349
|
+
foo: 'bar'
|
350
|
+
}
|
351
|
+
end
|
329
352
|
```
|
330
353
|
|
331
|
-
|
332
|
-
|
333
|
-
|
354
|
+
Very useful with https://github.com/vedmack/yadcf to provide values for dropdown filters.
|
355
|
+
|
356
|
+
|
357
|
+
### Setup the Controller action
|
334
358
|
|
335
|
-
|
336
|
-
Set up the controller to respond to JSON
|
359
|
+
Set the controller to respond to JSON
|
337
360
|
|
338
361
|
```ruby
|
339
362
|
def index
|
@@ -346,31 +369,10 @@ end
|
|
346
369
|
|
347
370
|
Don't forget to make sure the proper route has been added to `config/routes.rb`.
|
348
371
|
|
372
|
+
[See here](#options) to inject params in the `UserDatatable`.
|
349
373
|
|
350
|
-
###
|
374
|
+
### Wire up the Javascript
|
351
375
|
|
352
|
-
* Set up an html `<table>` with a `<thead>` and `<tbody>`
|
353
|
-
* Add in your table headers if desired
|
354
|
-
* Don't add any rows to the body of the table, datatables does this automatically
|
355
|
-
* Add a data attribute to the `<table>` tag with the url of the JSON feed
|
356
|
-
|
357
|
-
The resulting view may look like this:
|
358
|
-
|
359
|
-
```html
|
360
|
-
<table id="users-table", data-source="<%= users_path(format: :json) %>">
|
361
|
-
<thead>
|
362
|
-
<tr>
|
363
|
-
<th>First Name</th>
|
364
|
-
<th>Last Name</th>
|
365
|
-
<th>Brief Bio</th>
|
366
|
-
</tr>
|
367
|
-
</thead>
|
368
|
-
<tbody>
|
369
|
-
</tbody>
|
370
|
-
</table>
|
371
|
-
```
|
372
|
-
|
373
|
-
### Javascript
|
374
376
|
Finally, the javascript to tie this all together. In the appropriate `coffee` file:
|
375
377
|
|
376
378
|
```coffeescript
|
@@ -404,12 +406,13 @@ jQuery(document).ready(function() {
|
|
404
406
|
});
|
405
407
|
```
|
406
408
|
|
409
|
+
|
407
410
|
### Additional Notes
|
408
411
|
|
409
|
-
####
|
412
|
+
#### Columns syntax
|
410
413
|
|
411
|
-
|
412
|
-
the array
|
414
|
+
Since version `0.3.0`, we are implementing a pseudo code way of declaring
|
415
|
+
the array columns to use when querying the database.
|
413
416
|
|
414
417
|
Example. Suppose we have the following models: `User`, `PurchaseOrder`,
|
415
418
|
`Purchase::LineItem` and we need to have several columns from those models
|
@@ -418,8 +421,8 @@ available in our datatable to search and sort by.
|
|
418
421
|
```ruby
|
419
422
|
# we use the ModelName.column_name notation to declare our columns
|
420
423
|
|
421
|
-
def
|
422
|
-
@
|
424
|
+
def view_columns
|
425
|
+
@view_columns ||= [
|
423
426
|
'User.first_name',
|
424
427
|
'User.last_name',
|
425
428
|
'PurchaseOrder.number',
|
@@ -429,18 +432,11 @@ def searchable_columns
|
|
429
432
|
'Purchase::LineItem.item_total'
|
430
433
|
]
|
431
434
|
end
|
432
|
-
|
433
|
-
def sortable_columns
|
434
|
-
@sortable_columns ||= [
|
435
|
-
'User.first_name',
|
436
|
-
'User.last_name',
|
437
|
-
'PurchaseOrder.number',
|
438
|
-
'PurchaseOrder.created_at'
|
439
|
-
]
|
440
|
-
end
|
441
435
|
```
|
442
436
|
|
443
|
-
|
437
|
+
|
438
|
+
#### What if the datatable itself is namespaced?
|
439
|
+
|
444
440
|
Example: what if the datatable is namespaced into an `Admin` module?
|
445
441
|
|
446
442
|
```ruby
|
@@ -453,8 +449,8 @@ end
|
|
453
449
|
Taking the same models and columns, we would define it like this:
|
454
450
|
|
455
451
|
```ruby
|
456
|
-
def
|
457
|
-
@
|
452
|
+
def view_columns
|
453
|
+
@view_columns ||= [
|
458
454
|
'::User.first_name',
|
459
455
|
'::User.last_name',
|
460
456
|
'::PurchaseOrder.number',
|
@@ -468,20 +464,17 @@ end
|
|
468
464
|
|
469
465
|
Pretty much like you would do it, if you were inside a namespaced controller.
|
470
466
|
|
471
|
-
#### What if I'm using Oracle?
|
472
|
-
|
473
|
-
We have recently merged and released a contribution from [lutechspa](https://github.com/lutechspa) that makes this gem work with Oracle (tested in version 11g). You can [take a look at this sample repo](https://github.com/paoloripamonti/oracle-ajax-datatable) to get an idea on how to set things up.
|
474
467
|
|
475
468
|
#### Searching on non text-based columns
|
476
469
|
|
477
470
|
It always comes the time when you need to add a non-string/non-text based
|
478
|
-
column to the `@
|
471
|
+
column to the `@view_columns` array, so you can perform searches against
|
479
472
|
these column types (example: numeric, date, time).
|
480
473
|
|
481
474
|
We recently added the ability to (automatically) typecast these column types
|
482
475
|
and have this scenario covered. Please note however, if you are using
|
483
|
-
something different from `postgresql` (with the `:pg` gem), like `
|
484
|
-
`
|
476
|
+
something different from `postgresql` (with the `:pg` gem), like `mysql` or
|
477
|
+
`sqlite`, then you need to add an initializer in your application's
|
485
478
|
`config/initializers` directory.
|
486
479
|
|
487
480
|
If you don't perform this step (again, if using something different from
|
@@ -498,7 +491,7 @@ You have two options to create this initializer:
|
|
498
491
|
|
499
492
|
To use the generator, from the terminal execute:
|
500
493
|
|
501
|
-
```
|
494
|
+
```sh
|
502
495
|
$ bundle exec rails generate datatable:config
|
503
496
|
```
|
504
497
|
|
@@ -507,21 +500,19 @@ with the following content:
|
|
507
500
|
|
508
501
|
```ruby
|
509
502
|
AjaxDatatablesRails.configure do |config|
|
510
|
-
# available options for db_adapter are: :
|
503
|
+
# available options for db_adapter are: :pg, :mysql, :mysql2, :sqlite, :sqlite3
|
511
504
|
# config.db_adapter = :pg
|
512
505
|
|
513
|
-
# available options for
|
514
|
-
# config.
|
506
|
+
# available options for orm are: :active_record, :mongoid
|
507
|
+
# config.orm = :active_record
|
515
508
|
end
|
516
509
|
```
|
517
510
|
|
518
511
|
Uncomment the `config.db_adapter` line and set the corresponding value to your
|
519
512
|
database and gem. This is all you need.
|
520
513
|
|
521
|
-
Uncomment the `config.
|
522
|
-
included in your project. It defaults to `
|
523
|
-
passing `offset` and `limit` at the database level (through `ActiveRecord`
|
524
|
-
of course).
|
514
|
+
Uncomment the `config.orm` line to set `active_record or mongoid` if
|
515
|
+
included in your project. It defaults to `active_record`.
|
525
516
|
|
526
517
|
If you want to make the file from scratch, just copy the above code block into
|
527
518
|
a file inside the `config/initializers` directory.
|
@@ -549,16 +540,17 @@ class MyCustomDatatable < AjaxDatatablesRails::Base
|
|
549
540
|
# example: mapping the 2d jsonified array returned.
|
550
541
|
def data
|
551
542
|
records.map do |record|
|
552
|
-
|
553
|
-
link_to(record.fname, edit_resource_path(record)),
|
554
|
-
mail_to(record.email),
|
543
|
+
{
|
544
|
+
first_name: link_to(record.fname, edit_resource_path(record)),
|
545
|
+
email: mail_to(record.email),
|
555
546
|
# other attributes
|
556
|
-
|
547
|
+
}
|
557
548
|
end
|
558
549
|
end
|
559
550
|
end
|
560
551
|
```
|
561
552
|
|
553
|
+
|
562
554
|
#### Options
|
563
555
|
|
564
556
|
An `AjaxDatatablesRails::Base` inherited class can accept an options hash at
|
@@ -570,14 +562,19 @@ class UnrespondedMessagesDatatable < AjaxDatatablesRails::Base
|
|
570
562
|
end
|
571
563
|
|
572
564
|
datatable = UnrespondedMessagesDatatable.new(view_context,
|
573
|
-
{ :
|
565
|
+
{ user: current_user, from: 1.month.ago }
|
574
566
|
)
|
575
567
|
```
|
568
|
+
|
576
569
|
So, now inside your class code, you can use those options like this:
|
577
570
|
|
578
571
|
|
579
572
|
```ruby
|
580
573
|
# let's see an example
|
574
|
+
def user
|
575
|
+
@user ||= options[:user]
|
576
|
+
end
|
577
|
+
|
581
578
|
def from
|
582
579
|
@from ||= options[:from].beginning_of_day
|
583
580
|
end
|
@@ -587,10 +584,11 @@ def to
|
|
587
584
|
end
|
588
585
|
|
589
586
|
def get_raw_records
|
590
|
-
|
587
|
+
user.messages.unresponded.where(received_at: from..to)
|
591
588
|
end
|
592
589
|
```
|
593
590
|
|
591
|
+
|
594
592
|
#### Generator Syntax
|
595
593
|
|
596
594
|
Also, a class that inherits from `AjaxDatatablesRails::Base` is not tied to an
|
@@ -598,7 +596,7 @@ existing model, module, constant or any type of class in your Rails app.
|
|
598
596
|
You can pass a name to your datatable class like this:
|
599
597
|
|
600
598
|
|
601
|
-
```
|
599
|
+
```sh
|
602
600
|
$ rails generate datatable users
|
603
601
|
# returns a users_datatable.rb file with a UsersDatatable class
|
604
602
|
|
@@ -609,21 +607,23 @@ $ rails generate datatable UnrespondedMessages
|
|
609
607
|
# returns an unresponded_messages_datatable.rb file with an UnrespondedMessagesDatatable class
|
610
608
|
```
|
611
609
|
|
612
|
-
|
613
610
|
In the end, it's up to the developer which model(s), scope(s), relationship(s)
|
614
611
|
(or else) to employ inside the datatable class to retrieve records from the
|
615
612
|
database.
|
616
613
|
|
614
|
+
|
617
615
|
## Tutorial
|
618
616
|
|
619
|
-
Tutorial for Integrating `ajax-
|
617
|
+
Tutorial for Integrating `ajax-datatables-rails` on Rails 4.
|
620
618
|
|
621
|
-
[Part-1 The-Installation](https://github.com/
|
619
|
+
[Part-1 The-Installation](https://github.com/jbox-web/ajax-datatables-rails/wiki/Part-1----The-Installation)
|
622
620
|
|
623
|
-
[Part 2 The Datatables with ajax functionality](https://github.com/
|
621
|
+
[Part 2 The Datatables with ajax functionality](https://github.com/jbox-web/ajax-datatables-rails/wiki/Part-2-The-Datatables-with-ajax-functionality)
|
624
622
|
|
625
623
|
The complete project code for this tutorial series is available on [github](https://github.com/trkrameshkumar/simple_app).
|
626
624
|
|
625
|
+
Another sample project [code](https://github.com/ajahongir/ajax-datatables-rails-v-0-4-0-how-to). Its real world example.
|
626
|
+
|
627
627
|
|
628
628
|
## Contributing
|
629
629
|
|