Skip to content

Commit 70d4b27

Browse files
committed
[DRAFT] drafts changes for version 0.3.0
* found a better way to declare models and columns inside the searchable and sortable columns methods * for the time being, the old way of declaring such columns will be supported, but it will display a deprecation warning.
1 parent 1895169 commit 70d4b27

File tree

5 files changed

+171
-107
lines changed

5 files changed

+171
-107
lines changed

README.md

Lines changed: 94 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,12 @@ Take a look [here](#generator-syntax) for an explanation about the generator syn
7272
# include AjaxDatatablesRails::Extensions::SimplePaginator
7373

7474
def sortable_columns
75-
# list columns inside the Array in string dot notation.
76-
# Example: 'users.email'
75+
# Declare strings in this format: ModelName.column_name
7776
@sortable_columns ||= []
7877
end
7978

8079
def searchable_columns
81-
# list columns inside the Array in string dot notation.
82-
# Example: 'users.email'
80+
# Declare strings in this format: ModelName.column_name
8381
@searchable_columns ||= []
8482
end
8583
```
@@ -90,23 +88,28 @@ the gems bundled in your project. For example, if your models are using `Kaminar
9088

9189
* For `sortable_columns`, assign an array of the database columns that correspond to the columns in our view table. For example `[users.f_name, users.l_name, users.bio]`. This array is used for sorting by various columns.
9290

93-
* For `searchable_columns`, assign an array of the database columns that you want searchable by datatables. For example `[users.f_name, users.l_name]`
91+
* For `searchable_columns`, assign an array of the database columns that you want searchable by datatables. Suppose we need to sort and search users `:first_name`, `last_name` and `bio`.
9492

9593
This gives us:
9694

9795
```ruby
9896
include AjaxDatatablesRails::Extensions::Kaminari
9997

10098
def sortable_columns
101-
@sortable_columns ||= ['users.f_name', 'users.l_name', 'users.bio']
99+
@sortable_columns ||= %w(User.first_name User.last_name User.bio)
100+
# this is equal to:
101+
# @sortable_columns ||= ['User.first_name', 'User.last_name', 'User.bio']
102102
end
103103

104104
def searchable_columns
105-
@searchable_columns ||= ['users.f_name', 'users.l_name']
105+
@searchable_columns ||= %w(User.first_name User.last_name User.bio)
106+
# this is equal to:
107+
# @searchable_columns ||= ['User.first_name', 'User.last_name', 'User.bio']
106108
end
107109
```
108110

109-
[See here](#searching-on-non-text-based-columns) for notes regarding database config (if using something different from `postgre`).
111+
* [See here](#searching-on-non-text-based-columns) for notes about the `searchable_columns` settings (if using something different from `postgre`).
112+
* [Read these notes](#searchable-and-sortable-columns-syntax) about considerations for the `searchable_columns` and `sortable_columns` methods.
110113

111114
### Map data
112115
```ruby
@@ -126,8 +129,8 @@ This method builds a 2d array that is used by datatables to construct the html t
126129
def data
127130
records.map do |record|
128131
[
129-
record.f_name,
130-
record.l_name,
132+
record.first_name,
133+
record.last_name,
131134
record.bio
132135
]
133136
end
@@ -174,27 +177,27 @@ We want to sort and search on all columns of the list. The related definition wo
174177

175178
def sortable_columns
176179
@sortable_columns ||= [
177-
'coursetypes.name',
178-
'courses.name',
179-
'events.title',
180-
'events.event_start',
181-
'events.event_end',
182-
'contacts.last_name',
183-
'competency_types.name',
184-
'events.status'
180+
'Coursetype.name',
181+
'Course.name',
182+
'Event.title',
183+
'Event.event_start',
184+
'Event.event_end',
185+
'Contact.last_name',
186+
'CompetencyType.name',
187+
'Event.status'
185188
]
186189
end
187190

188191
def searchable_columns
189192
@searchable_columns ||= [
190-
'coursetypes.name',
191-
'courses.name',
192-
'events.title',
193-
'events.event_start',
194-
'events.event_end',
195-
'contacts.last_name',
196-
'competency_types.name',
197-
'events.status'
193+
'Coursetype.name',
194+
'Course.name',
195+
'Event.title',
196+
'Event.event_start',
197+
'Event.event_end',
198+
'Contact.last_name',
199+
'CompetencyType.name',
200+
'Event.status'
198201
]
199202
end
200203

@@ -230,38 +233,6 @@ So the query using the `.includes()` method is:
230233
end
231234
```
232235

233-
#### NOTE for model class that different from table name
234-
currently model class name detected by singularize the table name
235-
so if your table name is different, or you have namespaced model, you should set the model name like this
236-
237-
create the `setup` method (`setup` method will be executed when AjaxDatatablesRails class initialized)
238-
239-
then create `set_model_class` block inside `setup` method
240-
241-
```ruby
242-
def setup
243-
set_model_class do |klass|
244-
klass.users = Employee
245-
end
246-
end
247-
```
248-
now you can use `users.name` at `sortable_columns` and `searchable_columns` methods
249-
```ruby
250-
@sortable_columns ||= [ 'users.name']
251-
```
252-
253-
##### TIPS, you can use above step to abbreviate long namespaced model
254-
```ruby
255-
def setup
256-
set_model_class do |klass|
257-
klass.requests = Statistics::Request
258-
klass.sessions = Statistics::Session
259-
end
260-
end
261-
def searchable_columns
262-
@sortable_columns ||= [ 'requests.foo', 'sessions.bar']
263-
end
264-
```
265236

266237
### Controller
267238
Set up the controller to respond to JSON
@@ -277,15 +248,17 @@ end
277248

278249
Don't forget to make sure the proper route has been added to `config/routes.rb`.
279250

251+
280252
### View
253+
281254
* Set up an html `<table>` with a `<thead>` and `<tbody>`
282255
* Add in your table headers if desired
283256
* Don't add any rows to the body of the table, datatables does this automatically
284257
* Add a data attribute to the `<table>` tag with the url of the JSON feed
285258

286259
The resulting view may look like this:
287260

288-
```erb
261+
```html
289262
<table id="users-table", data-source="<%= users_path(format: :json) %>">
290263
<thead>
291264
<tr>
@@ -300,9 +273,11 @@ The resulting view may look like this:
300273
```
301274

302275
### Javascript
303-
Finally, the javascript to tie this all together. In the appropriate `js.coffee` file:
276+
Finally, the javascript to tie this all together. In the appropriate `coffee` file:
304277

305278
```coffeescript
279+
# users.coffee
280+
306281
$ ->
307282
$('#users-table').dataTable
308283
processing: true
@@ -333,6 +308,65 @@ jQuery(document).ready(function() {
333308

334309
### Additional Notes
335310

311+
#### Searchable and Sortable columns syntax
312+
313+
Starting on version `0.3.0`, we are implementing a pseudo code way of declaring the array of both `searchable_columns` and `sortable_columns` method.
314+
315+
Example. Suppose we have the following models: `User`, `PurchaseOrder`, `Purchase::LineItem` and we need to have several columns from those models available in our datatable to search and sort by.
316+
317+
```ruby
318+
# we use the ModelName.column_name notation to declare our columns
319+
320+
def searchable_columns
321+
@searchable_columns ||= [
322+
'User.first_name',
323+
'User.last_name',
324+
'PurchaseOrder.number',
325+
'PurchaseOrder.created_at',
326+
'Purchase::LineItem.quantity',
327+
'Purchase::LineItem.unit_price',
328+
'Purchase::LineItem.item_total'
329+
]
330+
end
331+
332+
def sortable_columns
333+
@sortable_columns ||= [
334+
'User.first_name',
335+
'User.last_name',
336+
'PurchaseOrder.number',
337+
'PurchaseOrder.created_at'
338+
]
339+
end
340+
```
341+
342+
##### What if the datatable itself is namespaced?
343+
Example: what if the datatable is namespaced into an `Admin` module?
344+
345+
```ruby
346+
module Admin
347+
class PurchasesDatatable < AjaxDatatablesRails::Base
348+
end
349+
end
350+
```
351+
352+
Taking the same models and columns, we would define it like this:
353+
354+
```ruby
355+
def searchable_columns
356+
@searchable_columns ||= [
357+
'::User.first_name',
358+
'::User.last_name',
359+
'::PurchaseOrder.number',
360+
'::PurchaseOrder.created_at',
361+
'::Purchase::LineItem.quantity',
362+
'::Purchase::LineItem.unit_price',
363+
'::Purchase::LineItem.item_total'
364+
]
365+
end
366+
```
367+
368+
Pretty much like you would do it, if you were inside a namespaced controller.
369+
336370
#### Searching on non text-based columns
337371

338372
It always comes the time when you need to add a non-string/non-text based column to the `@searchable_columns` array, so you can perform searches against these column types (example: numeric, date, time).

lib/ajax-datatables-rails/base.rb

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,6 @@ class MethodNotImplementedError < StandardError; end
99
def initialize(view, options = {})
1010
@view = view
1111
@options = options
12-
setup
13-
end
14-
15-
def set_model_class
16-
@models ||= AjaxDatatablesRails::Models.new
17-
yield @models
18-
end
19-
20-
def setup
21-
end
22-
23-
def models
24-
@models ||= AjaxDatatablesRails::Models.new
2512
end
2613

2714
def config
@@ -59,6 +46,16 @@ def as_json(options = {})
5946
}
6047
end
6148

49+
def self.deprecated(message, caller = Kernel.caller[1])
50+
warning = caller + ": " + message
51+
52+
if(respond_to?(:logger) && logger.present?)
53+
logger.warn(warning)
54+
else
55+
warn(warning)
56+
end
57+
end
58+
6259
private
6360

6461
def records
@@ -116,12 +113,26 @@ def build_conditions_for(query)
116113
end
117114

118115
def search_condition(column, value)
116+
if column[0] == column.downcase[0]
117+
::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'
118+
return deprecated_search_condition(column, value)
119+
else
120+
return new_search_condition(column, value)
121+
end
122+
end
123+
124+
def new_search_condition(column, value)
125+
model, column = column.split('.')
126+
model = model.constantize
127+
casted_column = ::Arel::Nodes::NamedFunction.new('CAST', [model.arel_table[column.to_sym].as(typecast)])
128+
casted_column.matches("%#{value}%")
129+
end
130+
131+
def deprecated_search_condition(column, value)
119132
model, column = column.split('.')
120-
model_class = models[model]
121-
model_class = model.singularize.titleize.gsub( / /, '' ).safe_constantize if model_class.nil?
122-
raise("Model with class name #{model} not found") if model_class.nil?
133+
model = model.singularize.titleize.gsub( / /, '' ).constantize
123134

124-
casted_column = ::Arel::Nodes::NamedFunction.new('CAST', [model_class.arel_table[column.to_sym].as(typecast)])
135+
casted_column = ::Arel::Nodes::NamedFunction.new('CAST', [model.arel_table[column.to_sym].as(typecast)])
125136
casted_column.matches("%#{value}%")
126137
end
127138

@@ -154,11 +165,19 @@ def per_page
154165
end
155166

156167
def sort_column(item)
157-
column = sortable_columns[item[:column].to_i]
158-
return nil if column.nil?
159-
model, col = column.split(".")
160-
return [models[model].table_name.to_s, col].join(".") unless models[model].nil?
161-
column
168+
new_sort_column(item)
169+
rescue
170+
::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'
171+
deprecated_sort_column(item)
172+
end
173+
174+
def deprecated_sort_column(item)
175+
sortable_columns[item['column'].to_i]
176+
end
177+
178+
def new_sort_column(item)
179+
model, column = sortable_columns[item[:column].to_i].split('.')
180+
col = [model.constantize.table_name, column].join('.')
162181
end
163182

164183
def sort_direction(item)

lib/ajax-datatables-rails/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module AjaxDatatablesRails
2-
VERSION = '0.2.1'
2+
VERSION = '0.3.0'
33
end

lib/generators/rails/templates/datatable.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@ class <%= @datatable_name %>Datatable < AjaxDatatablesRails::Base
66
# include AjaxDatatablesRails::Extensions::SimplePaginator
77

88
def sortable_columns
9-
# list columns inside the Array in string dot notation.
10-
# Example: 'users.email'
9+
# Declare strings in this format: ModelName.column_name
1110
@sortable_columns ||= []
1211
end
1312

1413
def searchable_columns
15-
# list columns inside the Array in string dot notation.
16-
# Example: 'users.email'
14+
# Declare strings in this format: ModelName.column_name
1715
@searchable_columns ||= []
1816
end
1917

0 commit comments

Comments
 (0)