ajax-datatables-rails 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.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
|
-
[](https://github.com/jbox-web/ajax-datatables-rails/blob/master/LICENSE)
|
4
|
+
[](https://rubygems.org/gems/ajax-datatables-rails)
|
5
|
+
[](https://rubygems.org/gems/ajax-datatables-rails)
|
6
|
+
[](https://travis-ci.org/jbox-web/ajax-datatables-rails)
|
7
|
+
[](https://codeclimate.com/github/jbox-web/ajax-datatables-rails)
|
8
|
+
[](https://codeclimate.com/github/jbox-web/ajax-datatables-rails/coverage)
|
9
|
+
[](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
|
|