ajax-datatables-rails 0.2.1 → 0.3.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/CHANGELOG.md +33 -9
- data/README.md +224 -73
- data/ajax-datatables-rails.gemspec +30 -0
- data/lib/ajax-datatables-rails.rb +1 -0
- data/lib/ajax-datatables-rails/base.rb +68 -5
- data/lib/ajax-datatables-rails/config.rb +1 -0
- data/lib/ajax-datatables-rails/models.rb +6 -0
- data/lib/ajax-datatables-rails/version.rb +1 -1
- data/lib/generators/datatable/templates/ajax_datatables_rails_config.rb +3 -0
- data/lib/generators/rails/templates/datatable.rb +2 -9
- data/spec/ajax-datatables-rails/ajax_datatables_rails_spec.rb +87 -37
- data/spec/ajax-datatables-rails/kaminari_spec.rb +8 -5
- data/spec/ajax-datatables-rails/models_spec.rb +10 -0
- data/spec/ajax-datatables-rails/simple_paginator_spec.rb +3 -3
- data/spec/ajax-datatables-rails/will_paginate_spec.rb +6 -3
- data/spec/schema.rb +35 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/test_models.rb +21 -0
- metadata +40 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb40ce5ae30557f81c8a63451ab50f2e4c23c5f3
|
4
|
+
data.tar.gz: bad6eea562962c847c1b3cec96e83b65e950735a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9af79c2aa217a781f1f9fcad0eec6071ecd81ad4c350cd4ef60c3e74642f7e955988d54cd90e2085aeb8ca76d0536317e53bd422da4971216a8b801630c6e9b0
|
7
|
+
data.tar.gz: e840e32893f670972bc292788295fe18a713fa016b25327ef94eaeabaa0914b34f12d7c0df32f2f59d1a4affbc32cd01c16d0dd52f45818cc4e2b40e8e50c064
|
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,33 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 0.3.0 (unreleased yet)
|
4
|
+
* Changes to the `sortable_columns` and `searchable_columns` syntax as it
|
5
|
+
required us to do unnecessary guessing. New syntax is `ModelName.column_name`
|
6
|
+
or `Namespace::ModelName.column_name`. Old syntax of `table_name.column_name`
|
7
|
+
is still available to use, but prints a deprecation warning. Thanks to
|
8
|
+
[M. Saiqul Haq](https://github.com/saiqulhaq) for pointing this.
|
9
|
+
* Adds support to discover from received params if a column should be really
|
10
|
+
considered for sorting purposes. Thanks to [Zachariah Clay](https://github.com/mebezac)
|
11
|
+
for this contribution.
|
12
|
+
* Moves paginator settings to configuration initializer.
|
13
|
+
|
3
14
|
## 0.2.1
|
4
|
-
* Fix count method to work with select statements under Rails 4.1. Thanks to
|
5
|
-
|
6
|
-
* Edits to `README` documentation
|
7
|
-
|
8
|
-
|
9
|
-
*
|
15
|
+
* Fix count method to work with select statements under Rails 4.1. Thanks to
|
16
|
+
[Jason Mitchell](https://github.com/mitchej123) for the contribution.
|
17
|
+
* Edits to `README` documentation about the `options` hash. Thanks to
|
18
|
+
[Jonathan E Hogue](https://github.com/hoguej) for pointing out that previous
|
19
|
+
documentation was confusing and didn't address its usage properly.
|
20
|
+
* Edits to `README` documentation on complex model queries inside the
|
21
|
+
`get_raw_records` method. A round of applause to [Zoltan Paulovics](https://github.com/zpaulovics)
|
22
|
+
for contributing this awesome piece of documentation. :smile:
|
23
|
+
* Adds typecast step to `search_condition` method, so now we support having
|
24
|
+
non-text columns inside the `searchable_columns` array.
|
25
|
+
* Adds support for multi-column sorting and multi-term search. Thanks to
|
26
|
+
[Zoltan Paulovics](https://github.com/zpaulovics) for contributing this feature.
|
27
|
+
* Adds optional config initializer, so we can have a base to typecast non
|
28
|
+
text-based columns and perform searches depending on the use of `:mysql2`,
|
29
|
+
`:sqlite3` or `:pg`. Thanks to [M. Saiqul Haq](https://github.com/saiqulhaq)
|
30
|
+
for contributing this feature.
|
10
31
|
|
11
32
|
## 0.2.0
|
12
33
|
* This version works with jQuery dataTables ver. 1.10 and it's new API syntax.
|
@@ -29,12 +50,15 @@ Thanks to [iruca3](https://github.com/iruca3) for the fix.
|
|
29
50
|
* A user would have the option to stick to the base
|
30
51
|
`AjaxDatatablesRails::Extensions::SimplePaginator` or replace it with
|
31
52
|
`AjaxDatatablesRails::Extensions::Kaminari` or
|
32
|
-
`AjaxDatatablesRails::Extensions::WillPaginate`, depending on what he/she
|
53
|
+
`AjaxDatatablesRails::Extensions::WillPaginate`, depending on what he/she
|
54
|
+
is using to handle record pagination.
|
33
55
|
* Removes dependency to pass in a model name to the generator. This way,
|
34
|
-
the developer has more flexibility to implement whatever datatable feature is
|
56
|
+
the developer has more flexibility to implement whatever datatable feature is
|
57
|
+
required.
|
35
58
|
* Datatable constructor accepts an optional `options` hash to provide
|
36
59
|
more flexibility.
|
37
|
-
See [README](https://github.com/antillas21/ajax-datatables-rails/blob/master/README.mds#options)
|
60
|
+
See [README](https://github.com/antillas21/ajax-datatables-rails/blob/master/README.mds#options)
|
61
|
+
for examples.
|
38
62
|
* Sets generator inside the `Rails` namespace. To generate an
|
39
63
|
`AjaxDatatablesRails` child class, just execute the
|
40
64
|
generator like this: `$ rails generate datatable NAME`.
|
data/README.md
CHANGED
@@ -6,9 +6,11 @@
|
|
6
6
|
|
7
7
|
### Versions
|
8
8
|
|
9
|
-
[Datatables](http://datatables.net) recently released version 1.10
|
9
|
+
[Datatables](http://datatables.net) recently released version 1.10 (which
|
10
|
+
includes a new API and features) and deprecated version 1.9.
|
10
11
|
|
11
|
-
If you have dataTables 1.9 in your project and want to keep using it, please
|
12
|
+
If you have dataTables 1.9 in your project and want to keep using it, please
|
13
|
+
use this gem's version `0.1.x` in your `Gemfile`:
|
12
14
|
|
13
15
|
```ruby
|
14
16
|
# specific version number
|
@@ -18,21 +20,33 @@ gem 'ajax-datatables-rails', '0.1.2'
|
|
18
20
|
gem 'ajax-datatables-rails', git: 'git://github.com/antillas21/ajax-datatables-rails.git', branch: 'legacy'
|
19
21
|
```
|
20
22
|
|
21
|
-
If you have dataTables 1.10 in your project, then use the gem's latest version,
|
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.
|
23
25
|
|
24
26
|
|
25
27
|
## Description
|
26
28
|
|
27
|
-
Datatables is a nifty jquery plugin that adds the ability to paginate, sort,
|
29
|
+
Datatables is a nifty jquery plugin that adds the ability to paginate, sort,
|
30
|
+
and search your html tables. When dealing with large tables
|
31
|
+
(more than a couple hundred rows) however, we run into performance issues.
|
32
|
+
These can be fixed by using server-side pagination, but this breaks some
|
33
|
+
datatables functionality.
|
28
34
|
|
29
|
-
`ajax-datatables-rails` is a wrapper around datatable's ajax methods that allow
|
35
|
+
`ajax-datatables-rails` is a wrapper around datatable's ajax methods that allow
|
36
|
+
synchronization with server-side pagination in a rails app. It was inspired by
|
37
|
+
this [Railscast](http://railscasts.com/episodes/340-datatables). I needed to
|
38
|
+
implement a similar solution in a couple projects I was working on, so I
|
39
|
+
extracted a solution into a gem.
|
30
40
|
|
31
41
|
## ORM support
|
32
42
|
|
33
|
-
Currently `AjaxDatatablesRails` only supports `ActiveRecord` as ORM for
|
43
|
+
Currently `AjaxDatatablesRails` only supports `ActiveRecord` as ORM for
|
44
|
+
performing database queries.
|
34
45
|
|
35
|
-
Adding support for `Sequel`, `Mongoid` and `MongoMapper` is a planned feature
|
46
|
+
Adding support for `Sequel`, `Mongoid` and `MongoMapper` is a planned feature
|
47
|
+
for this gem. If you'd be interested in contributing to speed development,
|
48
|
+
please [open an issue](https://github.com/antillas21/ajax-datatables-rails/issues/new)
|
49
|
+
and get in touch.
|
36
50
|
|
37
51
|
## Installation
|
38
52
|
|
@@ -47,11 +61,16 @@ And then execute:
|
|
47
61
|
|
48
62
|
The `jquery-datatables-rails` gem is listed as a convenience, to ease adding
|
49
63
|
jQuery dataTables to your Rails project. You can always add the plugin assets
|
50
|
-
manually via the assets pipeline. If you decide to use the
|
64
|
+
manually via the assets pipeline. If you decide to use the
|
65
|
+
`jquery-datatables-rails` gem, please refer to its installation instructions
|
66
|
+
[here](https://github.com/rweng/jquery-datatables-rails).
|
51
67
|
|
52
68
|
## Usage
|
53
|
-
*The following examples assume that we are setting up ajax-datatables-rails for
|
54
|
-
|
69
|
+
*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
|
+
our db, because you __should be using it__, if not, please refer to the
|
72
|
+
[Searching on non text-based columns](#searching-on-non-text-based-columns)
|
73
|
+
entry in the Additional Notes section.*
|
55
74
|
|
56
75
|
### Generate
|
57
76
|
Run the following command:
|
@@ -59,38 +78,32 @@ Run the following command:
|
|
59
78
|
$ rails generate datatable User
|
60
79
|
|
61
80
|
|
62
|
-
This will generate a file named `user_datatable.rb` in `app/datatables`.
|
81
|
+
This will generate a file named `user_datatable.rb` in `app/datatables`.
|
82
|
+
Open the file and customize in the functions as directed by the comments.
|
63
83
|
|
64
84
|
Take a look [here](#generator-syntax) for an explanation about the generator syntax.
|
65
85
|
|
66
86
|
### Customize
|
67
87
|
```ruby
|
68
|
-
# uncomment the appropriate paginator module,
|
69
|
-
# depending on gems available in your project.
|
70
|
-
# include AjaxDatatablesRails::Extensions::Kaminari
|
71
|
-
# include AjaxDatatablesRails::Extensions::WillPaginate
|
72
|
-
# include AjaxDatatablesRails::Extensions::SimplePaginator
|
73
|
-
|
74
88
|
def sortable_columns
|
75
|
-
#
|
76
|
-
# Example: 'users.email'
|
89
|
+
# Declare strings in this format: ModelName.column_name
|
77
90
|
@sortable_columns ||= []
|
78
91
|
end
|
79
92
|
|
80
93
|
def searchable_columns
|
81
|
-
#
|
82
|
-
# Example: 'users.email'
|
94
|
+
# Declare strings in this format: ModelName.column_name
|
83
95
|
@searchable_columns ||= []
|
84
96
|
end
|
85
97
|
```
|
86
98
|
|
87
|
-
* For `
|
88
|
-
the
|
89
|
-
|
99
|
+
* For `sortable_columns`, assign an array of the database columns that
|
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.
|
90
103
|
|
91
|
-
* For `
|
92
|
-
|
93
|
-
|
104
|
+
* For `searchable_columns`, assign an array of the database columns that you
|
105
|
+
want searchable by datatables. Suppose we need to sort and search users
|
106
|
+
`:first_name`, `last_name` and `bio`.
|
94
107
|
|
95
108
|
This gives us:
|
96
109
|
|
@@ -98,15 +111,22 @@ This gives us:
|
|
98
111
|
include AjaxDatatablesRails::Extensions::Kaminari
|
99
112
|
|
100
113
|
def sortable_columns
|
101
|
-
@sortable_columns ||=
|
114
|
+
@sortable_columns ||= %w(User.first_name User.last_name User.bio)
|
115
|
+
# this is equal to:
|
116
|
+
# @sortable_columns ||= ['User.first_name', 'User.last_name', 'User.bio']
|
102
117
|
end
|
103
118
|
|
104
119
|
def searchable_columns
|
105
|
-
@searchable_columns ||=
|
120
|
+
@searchable_columns ||= %w(User.first_name User.last_name User.bio)
|
121
|
+
# this is equal to:
|
122
|
+
# @searchable_columns ||= ['User.first_name', 'User.last_name', 'User.bio']
|
106
123
|
end
|
107
124
|
```
|
108
125
|
|
109
|
-
[See here](#searching-on-non-text-based-columns) for notes
|
126
|
+
* [See here](#searching-on-non-text-based-columns) for notes about the
|
127
|
+
`searchable_columns` settings (if using something different from `postgre`).
|
128
|
+
* [Read these notes](#searchable-and-sortable-columns-syntax) about
|
129
|
+
considerations for the `searchable_columns` and `sortable_columns` methods.
|
110
130
|
|
111
131
|
### Map data
|
112
132
|
```ruby
|
@@ -120,21 +140,23 @@ def data
|
|
120
140
|
end
|
121
141
|
```
|
122
142
|
|
123
|
-
This method builds a 2d array that is used by datatables to construct the html
|
143
|
+
This method builds a 2d array that is used by datatables to construct the html
|
144
|
+
table. Insert the values you want on each column.
|
124
145
|
|
125
146
|
```ruby
|
126
147
|
def data
|
127
148
|
records.map do |record|
|
128
149
|
[
|
129
|
-
record.
|
130
|
-
record.
|
150
|
+
record.first_name,
|
151
|
+
record.last_name,
|
131
152
|
record.bio
|
132
153
|
]
|
133
154
|
end
|
134
155
|
end
|
135
156
|
```
|
136
157
|
|
137
|
-
[See here](#using-view-helpers) if you need to use view helpers in the
|
158
|
+
[See here](#using-view-helpers) if you need to use view helpers in the
|
159
|
+
returned 2d array, like `link_to`, `mail_to`, `resource_path`, etc.
|
138
160
|
|
139
161
|
#### Get Raw Records
|
140
162
|
```ruby
|
@@ -147,18 +169,31 @@ This is where your query goes.
|
|
147
169
|
|
148
170
|
```ruby
|
149
171
|
def get_raw_records
|
172
|
+
# suppose we need all User records
|
173
|
+
# Rails 4+
|
150
174
|
User.all
|
175
|
+
# Rails 3.x
|
176
|
+
# User.scoped
|
151
177
|
end
|
152
178
|
```
|
153
179
|
|
154
|
-
Obviously, you can construct your query as required for the use case the
|
155
|
-
|
156
|
-
|
180
|
+
Obviously, you can construct your query as required for the use case the
|
181
|
+
datatable is used. Example: `User.active.with_recent_messages`.
|
182
|
+
|
183
|
+
__IMPORTANT:__ Make sure to return an `ActiveRecord::Relation` object as the
|
184
|
+
end product of this method. Why? Because the result from this method, will
|
185
|
+
be chained (for now) to `ActiveRecord` methods for sorting, filtering
|
186
|
+
and pagination.
|
157
187
|
|
158
188
|
#### Associated and nested models
|
159
|
-
The previous example has only one single model. But what about if you have
|
189
|
+
The previous example has only one single model. But what about if you have
|
190
|
+
some associated nested models and in a report you want to show fields from
|
191
|
+
these tables.
|
192
|
+
|
193
|
+
Take an example that has an `Event, Course, Coursetype, Allocation, Teacher,
|
194
|
+
Contact, Competency and CompetencyType` models. We want to have a datatables
|
195
|
+
report which has the following column:
|
160
196
|
|
161
|
-
Take an example that has an `Event, Course, Coursetype, Allocation, Teacher, Contact, Competency and CompetencyType` models. We want to have a datatables report which has the following column:
|
162
197
|
```ruby
|
163
198
|
'coursetypes.name',
|
164
199
|
'courses.name',
|
@@ -169,32 +204,35 @@ Take an example that has an `Event, Course, Coursetype, Allocation, Teacher, Con
|
|
169
204
|
'competency_types.name',
|
170
205
|
'events.status'
|
171
206
|
```
|
172
|
-
|
207
|
+
|
208
|
+
We want to sort and search on all columns of the list. The related definition
|
209
|
+
would be:
|
210
|
+
|
173
211
|
```ruby
|
174
212
|
|
175
213
|
def sortable_columns
|
176
214
|
@sortable_columns ||= [
|
177
|
-
'
|
178
|
-
'
|
179
|
-
'
|
180
|
-
'
|
181
|
-
'
|
182
|
-
'
|
183
|
-
'
|
184
|
-
'
|
215
|
+
'Coursetype.name',
|
216
|
+
'Course.name',
|
217
|
+
'Event.title',
|
218
|
+
'Event.event_start',
|
219
|
+
'Event.event_end',
|
220
|
+
'Contact.last_name',
|
221
|
+
'CompetencyType.name',
|
222
|
+
'Event.status'
|
185
223
|
]
|
186
224
|
end
|
187
225
|
|
188
226
|
def searchable_columns
|
189
227
|
@searchable_columns ||= [
|
190
|
-
'
|
191
|
-
'
|
192
|
-
'
|
193
|
-
'
|
194
|
-
'
|
195
|
-
'
|
196
|
-
'
|
197
|
-
'
|
228
|
+
'Coursetype.name',
|
229
|
+
'Course.name',
|
230
|
+
'Event.title',
|
231
|
+
'Event.event_start',
|
232
|
+
'Event.event_end',
|
233
|
+
'Contact.last_name',
|
234
|
+
'CompetencyType.name',
|
235
|
+
'Event.status'
|
198
236
|
]
|
199
237
|
end
|
200
238
|
|
@@ -210,11 +248,29 @@ We want to sort and search on all columns of the list. The related definition wo
|
|
210
248
|
|
211
249
|
__Some comments for the above code:__
|
212
250
|
|
213
|
-
1. In the list we show `full_name`, but in `sortable_columns` and
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
251
|
+
1. In the list we show `full_name`, but in `sortable_columns` and
|
252
|
+
`searchable_columns` we use `last_name` from the `Contact` model. The reason
|
253
|
+
is we can use only database columns as sort or search fields and the full_name
|
254
|
+
is not a database field.
|
255
|
+
|
256
|
+
2. In the `get_raw_records` method we have quite a complex query having one to
|
257
|
+
many and may to many associations using the joins ActiveRecord method.
|
258
|
+
The joins will generate INNER JOIN relations in the SQL query. In this case,
|
259
|
+
we do not include all event in the report if we have events which is not
|
260
|
+
associated with any model record from the relation.
|
261
|
+
|
262
|
+
3. To have all event records in the list we should use the `.includes` method,
|
263
|
+
which generate LEFT OUTER JOIN relation of the SQL query.
|
264
|
+
__IMPORTANT:__ Make sure to append `.references(:related_model)` with any
|
265
|
+
associated model. That forces the eager loading of all the associated models
|
266
|
+
by one SQL query, and the search condition for any column works fine.
|
267
|
+
Otherwise the `:recordsFiltered => filter_records(get_raw_records).count(:all)`
|
268
|
+
will generate 2 SQL queries (one for the Event model, and then another for the
|
269
|
+
associated tables). The `:recordsFiltered => filter_records(get_raw_records).count(:all)`
|
270
|
+
will use only the first one to return from the ActiveRecord::Relation object
|
271
|
+
in `get_raw_records` and you will get an error message of __Unknown column
|
272
|
+
'yourtable.yourfield' in 'where clause'__ in case the search field value
|
273
|
+
is not empty.
|
218
274
|
|
219
275
|
So the query using the `.includes()` method is:
|
220
276
|
|
@@ -230,6 +286,7 @@ So the query using the `.includes()` method is:
|
|
230
286
|
end
|
231
287
|
```
|
232
288
|
|
289
|
+
|
233
290
|
### Controller
|
234
291
|
Set up the controller to respond to JSON
|
235
292
|
|
@@ -244,7 +301,9 @@ end
|
|
244
301
|
|
245
302
|
Don't forget to make sure the proper route has been added to `config/routes.rb`.
|
246
303
|
|
304
|
+
|
247
305
|
### View
|
306
|
+
|
248
307
|
* Set up an html `<table>` with a `<thead>` and `<tbody>`
|
249
308
|
* Add in your table headers if desired
|
250
309
|
* Don't add any rows to the body of the table, datatables does this automatically
|
@@ -252,7 +311,7 @@ Don't forget to make sure the proper route has been added to `config/routes.rb`.
|
|
252
311
|
|
253
312
|
The resulting view may look like this:
|
254
313
|
|
255
|
-
```
|
314
|
+
```html
|
256
315
|
<table id="users-table", data-source="<%= users_path(format: :json) %>">
|
257
316
|
<thead>
|
258
317
|
<tr>
|
@@ -267,9 +326,11 @@ The resulting view may look like this:
|
|
267
326
|
```
|
268
327
|
|
269
328
|
### Javascript
|
270
|
-
Finally, the javascript to tie this all together. In the appropriate `
|
329
|
+
Finally, the javascript to tie this all together. In the appropriate `coffee` file:
|
271
330
|
|
272
331
|
```coffeescript
|
332
|
+
# users.coffee
|
333
|
+
|
273
334
|
$ ->
|
274
335
|
$('#users-table').dataTable
|
275
336
|
processing: true
|
@@ -300,13 +361,86 @@ jQuery(document).ready(function() {
|
|
300
361
|
|
301
362
|
### Additional Notes
|
302
363
|
|
364
|
+
#### Searchable and Sortable columns syntax
|
365
|
+
|
366
|
+
Starting on version `0.3.0`, we are implementing a pseudo code way of declaring
|
367
|
+
the array of both `searchable_columns` and `sortable_columns` method.
|
368
|
+
|
369
|
+
Example. Suppose we have the following models: `User`, `PurchaseOrder`,
|
370
|
+
`Purchase::LineItem` and we need to have several columns from those models
|
371
|
+
available in our datatable to search and sort by.
|
372
|
+
|
373
|
+
```ruby
|
374
|
+
# we use the ModelName.column_name notation to declare our columns
|
375
|
+
|
376
|
+
def searchable_columns
|
377
|
+
@searchable_columns ||= [
|
378
|
+
'User.first_name',
|
379
|
+
'User.last_name',
|
380
|
+
'PurchaseOrder.number',
|
381
|
+
'PurchaseOrder.created_at',
|
382
|
+
'Purchase::LineItem.quantity',
|
383
|
+
'Purchase::LineItem.unit_price',
|
384
|
+
'Purchase::LineItem.item_total'
|
385
|
+
]
|
386
|
+
end
|
387
|
+
|
388
|
+
def sortable_columns
|
389
|
+
@sortable_columns ||= [
|
390
|
+
'User.first_name',
|
391
|
+
'User.last_name',
|
392
|
+
'PurchaseOrder.number',
|
393
|
+
'PurchaseOrder.created_at'
|
394
|
+
]
|
395
|
+
end
|
396
|
+
```
|
397
|
+
|
398
|
+
##### What if the datatable itself is namespaced?
|
399
|
+
Example: what if the datatable is namespaced into an `Admin` module?
|
400
|
+
|
401
|
+
```ruby
|
402
|
+
module Admin
|
403
|
+
class PurchasesDatatable < AjaxDatatablesRails::Base
|
404
|
+
end
|
405
|
+
end
|
406
|
+
```
|
407
|
+
|
408
|
+
Taking the same models and columns, we would define it like this:
|
409
|
+
|
410
|
+
```ruby
|
411
|
+
def searchable_columns
|
412
|
+
@searchable_columns ||= [
|
413
|
+
'::User.first_name',
|
414
|
+
'::User.last_name',
|
415
|
+
'::PurchaseOrder.number',
|
416
|
+
'::PurchaseOrder.created_at',
|
417
|
+
'::Purchase::LineItem.quantity',
|
418
|
+
'::Purchase::LineItem.unit_price',
|
419
|
+
'::Purchase::LineItem.item_total'
|
420
|
+
]
|
421
|
+
end
|
422
|
+
```
|
423
|
+
|
424
|
+
Pretty much like you would do it, if you were inside a namespaced controller.
|
425
|
+
|
303
426
|
#### Searching on non text-based columns
|
304
427
|
|
305
|
-
It always comes the time when you need to add a non-string/non-text based
|
428
|
+
It always comes the time when you need to add a non-string/non-text based
|
429
|
+
column to the `@searchable_columns` array, so you can perform searches against
|
430
|
+
these column types (example: numeric, date, time).
|
431
|
+
|
432
|
+
We recently added the ability to (automatically) typecast these column types
|
433
|
+
and have this scenario covered. Please note however, if you are using
|
434
|
+
something different from `postgresql` (with the `:pg` gem), like `mysql` or
|
435
|
+
`sqlite`, then you need to add an initializer in your application's
|
436
|
+
`config/initializers` directory.
|
306
437
|
|
307
|
-
|
438
|
+
If you don't perform this step (again, if using something different from
|
439
|
+
`postgresql`), your database will complain that it does not understand the
|
440
|
+
default typecast used to enable such searches.
|
308
441
|
|
309
|
-
|
442
|
+
|
443
|
+
#### Configuration initializer
|
310
444
|
|
311
445
|
You have two options to create this initializer:
|
312
446
|
|
@@ -319,24 +453,36 @@ To use the generator, from the terminal execute:
|
|
319
453
|
$ bundle exec rails generate datatable:config
|
320
454
|
```
|
321
455
|
|
322
|
-
Doing so, will create the `config/initializers/ajax_datatables_rails.rb` file
|
456
|
+
Doing so, will create the `config/initializers/ajax_datatables_rails.rb` file
|
457
|
+
with the following content:
|
323
458
|
|
324
459
|
```ruby
|
325
460
|
AjaxDatatablesRails.configure do |config|
|
326
461
|
# available options for db_adapter are: :pg, :mysql2, :sqlite3
|
327
462
|
# config.db_adapter = :pg
|
463
|
+
|
464
|
+
# available options for paginator are: :simple_paginator, :kaminari, :will_paginate
|
465
|
+
# config.paginator = :simple_paginator
|
328
466
|
end
|
329
467
|
```
|
330
468
|
|
331
469
|
Uncomment the `config.db_adapter` line and set the corresponding value to your
|
332
470
|
database and gem. This is all you need.
|
333
471
|
|
334
|
-
|
472
|
+
Uncomment the `config.paginator` line to set `kaminari or will_paginate` if
|
473
|
+
included in your project. It defaults to `simple_paginator`, it falls back to
|
474
|
+
passing `offset` and `limit` at the database level (through `ActiveRecord`
|
475
|
+
of course).
|
476
|
+
|
477
|
+
If you want to make the file from scratch, just copy the above code block into
|
478
|
+
a file inside the `config/initializers` directory.
|
335
479
|
|
336
480
|
|
337
481
|
#### Using view helpers
|
338
482
|
|
339
|
-
Sometimes you'll need to use view helper methods like `link_to`, `h`, `mailto`,
|
483
|
+
Sometimes you'll need to use view helper methods like `link_to`, `h`, `mailto`,
|
484
|
+
`edit_resource_path` in the returned JSON representation returned by the `data`
|
485
|
+
method.
|
340
486
|
|
341
487
|
To have these methods available to be used, this is the way to go:
|
342
488
|
|
@@ -366,7 +512,8 @@ end
|
|
366
512
|
|
367
513
|
#### Options
|
368
514
|
|
369
|
-
An `AjaxDatatablesRails::Base` inherited class can accept an options hash at
|
515
|
+
An `AjaxDatatablesRails::Base` inherited class can accept an options hash at
|
516
|
+
initialization. This provides room for flexibility when required. Example:
|
370
517
|
|
371
518
|
```ruby
|
372
519
|
class UnrespondedMessagesDatatable < AjaxDatatablesRails::Base
|
@@ -397,7 +544,9 @@ end
|
|
397
544
|
|
398
545
|
#### Generator Syntax
|
399
546
|
|
400
|
-
Also, a class that inherits from `AjaxDatatablesRails::Base` is not tied to an
|
547
|
+
Also, a class that inherits from `AjaxDatatablesRails::Base` is not tied to an
|
548
|
+
existing model, module, constant or any type of class in your Rails app.
|
549
|
+
You can pass a name to your datatable class like this:
|
401
550
|
|
402
551
|
|
403
552
|
```
|
@@ -412,7 +561,9 @@ $ rails generate datatable UnrespondedMessages
|
|
412
561
|
```
|
413
562
|
|
414
563
|
|
415
|
-
In the end, it's up to the developer which model(s), scope(s), relationship(s)
|
564
|
+
In the end, it's up to the developer which model(s), scope(s), relationship(s)
|
565
|
+
(or else) to employ inside the datatable class to retrieve records from the
|
566
|
+
database.
|
416
567
|
|
417
568
|
## Tutorial
|
418
569
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ajax-datatables-rails/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "ajax-datatables-rails"
|
8
|
+
gem.version = AjaxDatatablesRails::VERSION
|
9
|
+
gem.authors = ["Joel Quenneville"]
|
10
|
+
gem.email = ["joel.quenneville@collegeplus.org"]
|
11
|
+
gem.description = %q{A gem that simplifies using datatables and hundreds of records via ajax}
|
12
|
+
gem.summary = %q{A wrapper around datatable's ajax methods that allow synchronization with server-side pagination in a rails app}
|
13
|
+
gem.homepage = ""
|
14
|
+
gem.required_ruby_version = Gem::Requirement.new(">= 1.9.3")
|
15
|
+
|
16
|
+
gem.files = Dir["{lib,spec}/**/*", "[A-Z]*"] - ["Gemfile.lock"]
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.require_path = "lib"
|
20
|
+
|
21
|
+
gem.add_dependency 'railties', '>= 3.1'
|
22
|
+
|
23
|
+
gem.add_development_dependency "rspec"
|
24
|
+
gem.add_development_dependency "generator_spec"
|
25
|
+
gem.add_development_dependency "pry"
|
26
|
+
gem.add_development_dependency "rake"
|
27
|
+
gem.add_development_dependency "sqlite3"
|
28
|
+
gem.add_development_dependency "rails", ">= 3.1.0"
|
29
|
+
gem.add_development_dependency "activerecord", ">= 4.1.6"
|
30
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'ajax-datatables-rails/version'
|
2
2
|
require 'ajax-datatables-rails/config'
|
3
|
+
require 'ajax-datatables-rails/models'
|
3
4
|
require 'ajax-datatables-rails/base'
|
4
5
|
require 'ajax-datatables-rails/extensions/simple_paginator'
|
5
6
|
require 'ajax-datatables-rails/extensions/kaminari'
|
@@ -9,6 +9,7 @@ module AjaxDatatablesRails
|
|
9
9
|
def initialize(view, options = {})
|
10
10
|
@view = view
|
11
11
|
@options = options
|
12
|
+
load_paginator
|
12
13
|
end
|
13
14
|
|
14
15
|
def config
|
@@ -46,6 +47,16 @@ module AjaxDatatablesRails
|
|
46
47
|
}
|
47
48
|
end
|
48
49
|
|
50
|
+
def self.deprecated(message, caller = Kernel.caller[1])
|
51
|
+
warning = caller + ": " + message
|
52
|
+
|
53
|
+
if(respond_to?(:logger) && logger.present?)
|
54
|
+
logger.warn(warning)
|
55
|
+
else
|
56
|
+
warn(warning)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
49
60
|
private
|
50
61
|
|
51
62
|
def records
|
@@ -54,9 +65,9 @@ module AjaxDatatablesRails
|
|
54
65
|
|
55
66
|
def fetch_records
|
56
67
|
records = get_raw_records
|
57
|
-
records = sort_records(records)
|
58
|
-
records = filter_records(records)
|
59
|
-
records = paginate_records(records) unless params[:length] == '-1'
|
68
|
+
records = sort_records(records) if params[:order].present?
|
69
|
+
records = filter_records(records) if params[:search].present?
|
70
|
+
records = paginate_records(records) unless params[:length].present? && params[:length] == '-1'
|
60
71
|
records
|
61
72
|
end
|
62
73
|
|
@@ -103,6 +114,22 @@ module AjaxDatatablesRails
|
|
103
114
|
end
|
104
115
|
|
105
116
|
def search_condition(column, value)
|
117
|
+
if column[0] == column.downcase[0]
|
118
|
+
::AjaxDatatablesRails::Base.deprecated '[DEPRECATED] Using table_name.column_name notation is deprecated. Please refer to: https://github.com/antillas21/ajax-datatables-rails#searchable-and-sortable-columns-syntax'
|
119
|
+
return deprecated_search_condition(column, value)
|
120
|
+
else
|
121
|
+
return new_search_condition(column, value)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def new_search_condition(column, value)
|
126
|
+
model, column = column.split('.')
|
127
|
+
model = model.constantize
|
128
|
+
casted_column = ::Arel::Nodes::NamedFunction.new('CAST', [model.arel_table[column.to_sym].as(typecast)])
|
129
|
+
casted_column.matches("%#{value}%")
|
130
|
+
end
|
131
|
+
|
132
|
+
def deprecated_search_condition(column, value)
|
106
133
|
model, column = column.split('.')
|
107
134
|
model = model.singularize.titleize.gsub( / /, '' ).constantize
|
108
135
|
|
@@ -139,12 +166,48 @@ module AjaxDatatablesRails
|
|
139
166
|
end
|
140
167
|
|
141
168
|
def sort_column(item)
|
142
|
-
|
169
|
+
new_sort_column(item)
|
170
|
+
rescue
|
171
|
+
::AjaxDatatablesRails::Base.deprecated '[DEPRECATED] Using table_name.column_name notation is deprecated. Please refer to: https://github.com/antillas21/ajax-datatables-rails#searchable-and-sortable-columns-syntax'
|
172
|
+
deprecated_sort_column(item)
|
173
|
+
end
|
174
|
+
|
175
|
+
def deprecated_sort_column(item)
|
176
|
+
sortable_columns[sortable_displayed_columns.index(item[:column])]
|
177
|
+
end
|
178
|
+
|
179
|
+
def new_sort_column(item)
|
180
|
+
model, column = sortable_columns[sortable_displayed_columns.index(item[:column])].split('.')
|
181
|
+
col = [model.constantize.table_name, column].join('.')
|
143
182
|
end
|
144
183
|
|
145
184
|
def sort_direction(item)
|
146
185
|
options = %w(desc asc)
|
147
|
-
options.include?(item[
|
186
|
+
options.include?(item[:dir]) ? item[:dir].upcase : 'ASC'
|
187
|
+
end
|
188
|
+
|
189
|
+
def sortable_displayed_columns
|
190
|
+
@sortable_displayed_columns ||= generate_sortable_displayed_columns
|
191
|
+
end
|
192
|
+
|
193
|
+
def generate_sortable_displayed_columns
|
194
|
+
@sortable_displayed_columns = []
|
195
|
+
params[:columns].each_value do |column|
|
196
|
+
@sortable_displayed_columns << column[:data] if column[:orderable] == 'true'
|
197
|
+
end
|
198
|
+
@sortable_displayed_columns
|
199
|
+
end
|
200
|
+
|
201
|
+
def load_paginator
|
202
|
+
case config.paginator
|
203
|
+
when :kaminari
|
204
|
+
extend Extensions::Kaminari
|
205
|
+
when :will_paginate
|
206
|
+
extend Extensions::WillPaginate
|
207
|
+
else
|
208
|
+
extend Extensions::SimplePaginator
|
209
|
+
end
|
210
|
+
self
|
148
211
|
end
|
149
212
|
end
|
150
213
|
end
|
@@ -1,4 +1,7 @@
|
|
1
1
|
AjaxDatatablesRails.configure do |config|
|
2
2
|
# available options for db_adapter are: :pg, :mysql2, :sqlite3
|
3
3
|
# config.db_adapter = :pg
|
4
|
+
|
5
|
+
# available options for paginator are: :simple_paginator, :kaminari, :will_paginate
|
6
|
+
# config.paginator = :simple_paginator
|
4
7
|
end
|
@@ -1,19 +1,12 @@
|
|
1
1
|
class <%= @datatable_name %>Datatable < AjaxDatatablesRails::Base
|
2
|
-
# uncomment the appropriate paginator module,
|
3
|
-
# depending on gems available in your project.
|
4
|
-
# include AjaxDatatablesRails::Extensions::Kaminari
|
5
|
-
# include AjaxDatatablesRails::Extensions::WillPaginate
|
6
|
-
# include AjaxDatatablesRails::Extensions::SimplePaginator
|
7
2
|
|
8
3
|
def sortable_columns
|
9
|
-
#
|
10
|
-
# Example: 'users.email'
|
4
|
+
# Declare strings in this format: ModelName.column_name
|
11
5
|
@sortable_columns ||= []
|
12
6
|
end
|
13
7
|
|
14
8
|
def searchable_columns
|
15
|
-
#
|
16
|
-
# Example: 'users.email'
|
9
|
+
# Declare strings in this format: ModelName.column_name
|
17
10
|
@searchable_columns ||= []
|
18
11
|
end
|
19
12
|
|
@@ -1,23 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe AjaxDatatablesRails::Base do
|
4
|
-
class Column
|
5
|
-
def matches(query)
|
6
|
-
[]
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
class User
|
11
|
-
def self.arel_table
|
12
|
-
{ :foo => Column.new }
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class UserData
|
17
|
-
def self.arel_table
|
18
|
-
{ :bar => Column.new }
|
19
|
-
end
|
20
|
-
end
|
21
4
|
|
22
5
|
params = {
|
23
6
|
:draw => '5',
|
@@ -95,17 +78,13 @@ describe AjaxDatatablesRails::Base do
|
|
95
78
|
describe '#sort_column' do
|
96
79
|
it 'returns a column name from the #sorting_columns array' do
|
97
80
|
sort_view = double(
|
98
|
-
'view',
|
99
|
-
:params => {
|
100
|
-
:order => {
|
101
|
-
'0' => { :column => '1' }
|
102
|
-
}
|
103
|
-
}
|
81
|
+
'view', :params => params
|
104
82
|
)
|
105
83
|
datatable = AjaxDatatablesRails::Base.new(sort_view)
|
106
|
-
datatable.
|
84
|
+
allow(datatable).to receive(:sortable_displayed_columns) { ["0", "1"] }
|
85
|
+
allow(datatable).to receive(:sortable_columns) { ['User.foo', 'User.bar', 'User.baz'] }
|
107
86
|
|
108
|
-
expect(datatable.send(:sort_column)).to eq('bar')
|
87
|
+
expect(datatable.send(:sort_column, sort_view.params[:order]["0"])).to eq('users.bar')
|
109
88
|
end
|
110
89
|
end
|
111
90
|
|
@@ -120,7 +99,7 @@ describe AjaxDatatablesRails::Base do
|
|
120
99
|
}
|
121
100
|
)
|
122
101
|
datatable = AjaxDatatablesRails::Base.new(sorting_view)
|
123
|
-
expect(datatable.send(:sort_direction)).to eq('DESC')
|
102
|
+
expect(datatable.send(:sort_direction, sorting_view.params[:order]["0"])).to eq('DESC')
|
124
103
|
end
|
125
104
|
|
126
105
|
it 'can only be one option from ASC or DESC' do
|
@@ -133,7 +112,70 @@ describe AjaxDatatablesRails::Base do
|
|
133
112
|
}
|
134
113
|
)
|
135
114
|
datatable = AjaxDatatablesRails::Base.new(sorting_view)
|
136
|
-
expect(datatable.send(:sort_direction)).to eq('ASC')
|
115
|
+
expect(datatable.send(:sort_direction, sorting_view.params[:order]["0"])).to eq('ASC')
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "#configure" do
|
120
|
+
let(:datatable) do
|
121
|
+
class FooDatatable < AjaxDatatablesRails::Base
|
122
|
+
end
|
123
|
+
|
124
|
+
FooDatatable.new view
|
125
|
+
end
|
126
|
+
|
127
|
+
context "when model class name is regular" do
|
128
|
+
it "should successfully get right model class" do
|
129
|
+
expect(
|
130
|
+
datatable.send(:search_condition, 'User.bar', 'bar')
|
131
|
+
).to be_a(Arel::Nodes::Matches)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context "when custom named model class" do
|
136
|
+
it "should successfully get right model class" do
|
137
|
+
expect(
|
138
|
+
datatable.send(:search_condition, 'Statistics::Request.bar', 'bar')
|
139
|
+
).to be_a(Arel::Nodes::Matches)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
context "when model class name camelcased" do
|
145
|
+
it "should successfully get right model class" do
|
146
|
+
expect(
|
147
|
+
datatable.send(:search_condition, 'PurchasedOrder.bar', 'bar')
|
148
|
+
).to be_a(Arel::Nodes::Matches)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context "when model class name is namespaced" do
|
153
|
+
it "should successfully get right model class" do
|
154
|
+
expect(
|
155
|
+
datatable.send(:search_condition, 'Statistics::Session.bar', 'bar')
|
156
|
+
).to be_a(Arel::Nodes::Matches)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context "when model class defined but not found" do
|
161
|
+
it "raise 'uninitialized constant'" do
|
162
|
+
expect {
|
163
|
+
datatable.send(:search_condition, 'UnexistentModel.bar', 'bar')
|
164
|
+
}.to raise_error(NameError, /uninitialized constant/)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context 'when using deprecated notation' do
|
169
|
+
it 'should successfully get right model class if exists' do
|
170
|
+
expect(
|
171
|
+
datatable.send(:search_condition, 'users.bar', 'bar')
|
172
|
+
).to be_a(Arel::Nodes::Matches)
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'should display a deprecated message' do
|
176
|
+
expect(AjaxDatatablesRails::Base).to receive(:deprecated)
|
177
|
+
datatable.send(:search_condition, 'users.bar', 'bar')
|
178
|
+
end
|
137
179
|
end
|
138
180
|
end
|
139
181
|
|
@@ -156,31 +198,38 @@ describe AjaxDatatablesRails::Base do
|
|
156
198
|
let(:results) { double('Collection', :offset => [], :limit => []) }
|
157
199
|
let(:view) { double('view', :params => params) }
|
158
200
|
let(:datatable) { AjaxDatatablesRails::Base.new(view) }
|
201
|
+
let(:records) { double('Array').as_null_object }
|
202
|
+
|
203
|
+
before(:each) do
|
204
|
+
allow(datatable).to receive(:sortable_columns) { ['User.foo', 'User.bar'] }
|
205
|
+
allow(datatable).to receive(:sortable_displayed_columns) { ["0", "1"] }
|
206
|
+
end
|
159
207
|
|
160
208
|
describe '#paginate_records' do
|
161
|
-
it '
|
162
|
-
|
163
|
-
|
164
|
-
)
|
209
|
+
it 'defaults to Extensions::SimplePaginator#paginate_records' do
|
210
|
+
allow(records).to receive_message_chain(:offset, :limit)
|
211
|
+
|
212
|
+
expect { datatable.send(:paginate_records, records) }.not_to raise_error
|
165
213
|
end
|
166
214
|
end
|
167
215
|
|
168
216
|
describe '#sort_records' do
|
169
217
|
it 'calls #order on a collection' do
|
170
|
-
results.
|
218
|
+
expect(results).to receive(:order)
|
171
219
|
datatable.send(:sort_records, results)
|
172
220
|
end
|
173
221
|
end
|
174
222
|
|
175
223
|
describe '#filter_records' do
|
176
|
-
let(:records) {
|
224
|
+
let(:records) { double('User', :where => []) }
|
177
225
|
let(:search_view) { double('view', :params => params) }
|
178
226
|
|
179
227
|
it 'applies search like functionality on a collection' do
|
180
228
|
datatable = AjaxDatatablesRails::Base.new(search_view)
|
181
|
-
datatable.
|
229
|
+
allow(datatable).to receive(:searchable_columns) { ['users.foo'] }
|
182
230
|
|
183
|
-
records.
|
231
|
+
expect(records).to receive(:where)
|
232
|
+
records.where
|
184
233
|
datatable.send(:filter_records, records)
|
185
234
|
end
|
186
235
|
end
|
@@ -191,9 +240,10 @@ describe AjaxDatatablesRails::Base do
|
|
191
240
|
|
192
241
|
it 'applies search like functionality on a collection' do
|
193
242
|
datatable = AjaxDatatablesRails::Base.new(search_view)
|
194
|
-
datatable.
|
243
|
+
allow(datatable).to receive(:searchable_columns) { ['user_datas.bar'] }
|
195
244
|
|
196
|
-
records.
|
245
|
+
expect(records).to receive(:where)
|
246
|
+
records.where
|
197
247
|
datatable.send(:filter_records, records)
|
198
248
|
end
|
199
249
|
end
|
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
class KaminariDatatable < AjaxDatatablesRails::Base
|
4
|
-
include AjaxDatatablesRails::Extensions::Kaminari
|
5
4
|
end
|
6
5
|
|
7
6
|
describe KaminariDatatable do
|
7
|
+
before(:each) do
|
8
|
+
allow_any_instance_of(AjaxDatatablesRails::Configuration).to receive(:paginator) { :kaminari }
|
9
|
+
end
|
10
|
+
|
8
11
|
describe '#paginate_records' do
|
9
12
|
let(:users_database) do
|
10
13
|
double('User',
|
@@ -18,15 +21,15 @@ describe KaminariDatatable do
|
|
18
21
|
let(:records) { users_database.all }
|
19
22
|
|
20
23
|
it 'calls #page on passed record collection' do
|
21
|
-
records.
|
24
|
+
expect(records).to receive(:page)
|
22
25
|
datatable.send(:paginate_records, records)
|
23
26
|
end
|
24
27
|
|
25
28
|
it 'calls #per_page on passed record collection' do
|
26
29
|
arry = double('Array', :per => [])
|
27
|
-
records.
|
28
|
-
arry.
|
30
|
+
allow(records).to receive(:page).and_return(arry)
|
31
|
+
expect(arry).to receive(:per)
|
29
32
|
datatable.send(:paginate_records, records)
|
30
33
|
end
|
31
34
|
end
|
32
|
-
end
|
35
|
+
end
|
@@ -18,14 +18,14 @@ describe SimplePaginateDatatable do
|
|
18
18
|
let(:records) { users_database.all }
|
19
19
|
|
20
20
|
it 'calls #offset on passed record collection' do
|
21
|
-
records.
|
21
|
+
expect(records).to receive(:offset)
|
22
22
|
datatable.send(:paginate_records, records)
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'calls #limit on passed record collection' do
|
26
26
|
arry = double('Array', :limit => [])
|
27
|
-
records.
|
28
|
-
arry.
|
27
|
+
allow(records).to receive(:offset).and_return(arry)
|
28
|
+
expect(arry).to receive(:limit)
|
29
29
|
datatable.send(:paginate_records, records)
|
30
30
|
end
|
31
31
|
end
|
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
class WillPaginateDatatable < AjaxDatatablesRails::Base
|
4
|
-
include AjaxDatatablesRails::Extensions::WillPaginate
|
5
4
|
end
|
6
5
|
|
7
6
|
describe WillPaginateDatatable do
|
7
|
+
before(:each) do
|
8
|
+
allow_any_instance_of(AjaxDatatablesRails::Configuration).to receive(:paginator) { :will_paginate }
|
9
|
+
end
|
10
|
+
|
8
11
|
describe '#paginate_records' do
|
9
12
|
let(:users_database) do
|
10
13
|
double('User',
|
@@ -18,8 +21,8 @@ describe WillPaginateDatatable do
|
|
18
21
|
let(:records) { users_database.all }
|
19
22
|
|
20
23
|
it 'calls #page and #per_page on passed record collection' do
|
21
|
-
records.
|
24
|
+
expect(records).to receive(:paginate).with(:page=>1, :per_page=>10)
|
22
25
|
datatable.send(:paginate_records, records)
|
23
26
|
end
|
24
27
|
end
|
25
|
-
end
|
28
|
+
end
|
data/spec/schema.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
ActiveRecord::Schema.define do
|
2
|
+
self.verbose = false
|
3
|
+
|
4
|
+
create_table :users, :force => true do |t|
|
5
|
+
t.string :username
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
|
10
|
+
create_table :user_data, :force => true do |t|
|
11
|
+
t.string :address
|
12
|
+
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
create_table :purchased_orders, :force => true do |t|
|
17
|
+
t.string :foo
|
18
|
+
t.string :bar
|
19
|
+
|
20
|
+
t.timestamps
|
21
|
+
end
|
22
|
+
|
23
|
+
create_table :statistics_requests, :force => true do |t|
|
24
|
+
t.string :baz
|
25
|
+
|
26
|
+
t.timestamps
|
27
|
+
end
|
28
|
+
|
29
|
+
create_table :statistics_sessions, :force => true do |t|
|
30
|
+
t.string :foo
|
31
|
+
t.integer :bar
|
32
|
+
|
33
|
+
t.timestamps
|
34
|
+
end
|
35
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,9 @@
|
|
1
1
|
require 'pry'
|
2
2
|
require 'rails'
|
3
|
+
require 'active_record'
|
3
4
|
require 'ajax-datatables-rails'
|
5
|
+
|
6
|
+
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
|
7
|
+
|
8
|
+
load File.dirname(__FILE__) + '/schema.rb'
|
9
|
+
require File.dirname(__FILE__) + '/test_models.rb'
|
data/spec/test_models.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
class User < ActiveRecord::Base
|
2
|
+
end
|
3
|
+
|
4
|
+
class UserData < ActiveRecord::Base
|
5
|
+
self.table_name = "user_data"
|
6
|
+
end
|
7
|
+
|
8
|
+
class PurchasedOrder < ActiveRecord::Base
|
9
|
+
end
|
10
|
+
|
11
|
+
module Statistics
|
12
|
+
def self.table_name_prefix
|
13
|
+
"statistics_"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Statistics::Request < ActiveRecord::Base
|
18
|
+
end
|
19
|
+
|
20
|
+
class Statistics::Session < ActiveRecord::Base
|
21
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ajax-datatables-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Quenneville
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: sqlite3
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: rails
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +108,20 @@ dependencies:
|
|
94
108
|
- - ">="
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: 3.1.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: activerecord
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 4.1.6
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 4.1.6
|
97
125
|
description: A gem that simplifies using datatables and hundreds of records via ajax
|
98
126
|
email:
|
99
127
|
- joel.quenneville@collegeplus.org
|
@@ -106,12 +134,14 @@ files:
|
|
106
134
|
- LICENSE
|
107
135
|
- README.md
|
108
136
|
- Rakefile
|
137
|
+
- ajax-datatables-rails.gemspec
|
109
138
|
- lib/ajax-datatables-rails.rb
|
110
139
|
- lib/ajax-datatables-rails/base.rb
|
111
140
|
- lib/ajax-datatables-rails/config.rb
|
112
141
|
- lib/ajax-datatables-rails/extensions/kaminari.rb
|
113
142
|
- lib/ajax-datatables-rails/extensions/simple_paginator.rb
|
114
143
|
- lib/ajax-datatables-rails/extensions/will_paginate.rb
|
144
|
+
- lib/ajax-datatables-rails/models.rb
|
115
145
|
- lib/ajax-datatables-rails/version.rb
|
116
146
|
- lib/generators/datatable/config_generator.rb
|
117
147
|
- lib/generators/datatable/templates/ajax_datatables_rails_config.rb
|
@@ -119,9 +149,12 @@ files:
|
|
119
149
|
- lib/generators/rails/templates/datatable.rb
|
120
150
|
- spec/ajax-datatables-rails/ajax_datatables_rails_spec.rb
|
121
151
|
- spec/ajax-datatables-rails/kaminari_spec.rb
|
152
|
+
- spec/ajax-datatables-rails/models_spec.rb
|
122
153
|
- spec/ajax-datatables-rails/simple_paginator_spec.rb
|
123
154
|
- spec/ajax-datatables-rails/will_paginate_spec.rb
|
155
|
+
- spec/schema.rb
|
124
156
|
- spec/spec_helper.rb
|
157
|
+
- spec/test_models.rb
|
125
158
|
homepage: ''
|
126
159
|
licenses: []
|
127
160
|
metadata: {}
|
@@ -133,7 +166,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
133
166
|
requirements:
|
134
167
|
- - ">="
|
135
168
|
- !ruby/object:Gem::Version
|
136
|
-
version: 1.9.
|
169
|
+
version: 1.9.3
|
137
170
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
171
|
requirements:
|
139
172
|
- - ">="
|
@@ -141,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
174
|
version: '0'
|
142
175
|
requirements: []
|
143
176
|
rubyforge_project:
|
144
|
-
rubygems_version: 2.
|
177
|
+
rubygems_version: 2.4.5
|
145
178
|
signing_key:
|
146
179
|
specification_version: 4
|
147
180
|
summary: A wrapper around datatable's ajax methods that allow synchronization with
|
@@ -149,6 +182,9 @@ summary: A wrapper around datatable's ajax methods that allow synchronization wi
|
|
149
182
|
test_files:
|
150
183
|
- spec/ajax-datatables-rails/ajax_datatables_rails_spec.rb
|
151
184
|
- spec/ajax-datatables-rails/kaminari_spec.rb
|
185
|
+
- spec/ajax-datatables-rails/models_spec.rb
|
152
186
|
- spec/ajax-datatables-rails/simple_paginator_spec.rb
|
153
187
|
- spec/ajax-datatables-rails/will_paginate_spec.rb
|
188
|
+
- spec/schema.rb
|
154
189
|
- spec/spec_helper.rb
|
190
|
+
- spec/test_models.rb
|