datatables-net 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 +7 -0
- data/CHANGELOG.md +73 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +618 -0
- data/Rakefile +14 -0
- data/lib/ajax-datatables-rails.rb +11 -0
- data/lib/ajax-datatables-rails/base.rb +205 -0
- data/lib/ajax-datatables-rails/config.rb +24 -0
- data/lib/ajax-datatables-rails/datatable/column.rb +106 -0
- data/lib/ajax-datatables-rails/datatable/datatable.rb +69 -0
- data/lib/ajax-datatables-rails/datatable/simple_order.rb +31 -0
- data/lib/ajax-datatables-rails/datatable/simple_search.rb +19 -0
- data/lib/ajax-datatables-rails/orm/active_record.rb +52 -0
- data/lib/ajax-datatables-rails/version.rb +3 -0
- data/lib/generators/datatable/config_generator.rb +17 -0
- data/lib/generators/datatable/templates/ajax_datatables_rails_config.rb +7 -0
- data/lib/generators/rails/datatable_generator.rb +27 -0
- data/lib/generators/rails/templates/datatable.rb +41 -0
- data/spec/ajax-datatables-rails/base_spec.rb +140 -0
- data/spec/ajax-datatables-rails/configuration_spec.rb +43 -0
- data/spec/ajax-datatables-rails/datatable/column_spec.rb +65 -0
- data/spec/ajax-datatables-rails/datatable/datatable_spec.rb +97 -0
- data/spec/ajax-datatables-rails/datatable/simple_order_spec.rb +12 -0
- data/spec/ajax-datatables-rails/datatable/simple_search_spec.rb +16 -0
- data/spec/ajax-datatables-rails/orm/active_record_filter_records_spec.rb +154 -0
- data/spec/ajax-datatables-rails/orm/active_record_paginate_records_spec.rb +51 -0
- data/spec/ajax-datatables-rails/orm/active_record_sort_records_spec.rb +42 -0
- data/spec/ajax-datatables-rails/orm/active_record_spec.rb +34 -0
- data/spec/schema.rb +43 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/test_helpers.rb +66 -0
- data/spec/test_models.rb +20 -0
- metadata +202 -0
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'AjaxDatatablesRails::Datatable::SimpleOrder' do
|
4
|
+
let(:options) { ActiveSupport::HashWithIndifferentAccess.new({"column"=>"1", "dir"=>"desc"}) }
|
5
|
+
let(:simple_order) { AjaxDatatablesRails::Datatable::SimpleOrder.new nil, options }
|
6
|
+
|
7
|
+
describe 'option methods' do
|
8
|
+
it 'sql query' do
|
9
|
+
expect(simple_order.query('firstname')).to eq('firstname DESC')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'AjaxDatatablesRails::Datatable::SimpleSearch' do
|
4
|
+
let(:options) { ActiveSupport::HashWithIndifferentAccess.new({"value"=>"search value", "regex"=>"true"}) }
|
5
|
+
let(:simple_search) { AjaxDatatablesRails::Datatable::SimpleSearch.new options }
|
6
|
+
|
7
|
+
describe 'option methods' do
|
8
|
+
it 'regexp?' do
|
9
|
+
expect(simple_search.regexp?).to be(true)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'value' do
|
13
|
+
expect(simple_search.value).to eq("search value")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'AjaxDatatablesRails::ORM::ActiveRecord#filter_records' do
|
4
|
+
let(:view) { double('view', params: sample_params) }
|
5
|
+
let(:datatable) { ComplexDatatable.new(view) }
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
AjaxDatatablesRails.configure do |config|
|
9
|
+
config.db_adapter = :sqlite
|
10
|
+
config.orm = :active_record
|
11
|
+
end
|
12
|
+
|
13
|
+
User.create(username: 'johndoe', email: 'johndoe@example.com')
|
14
|
+
User.create(username: 'msmith', email: 'mary.smith@example.com')
|
15
|
+
end
|
16
|
+
|
17
|
+
after(:each) do
|
18
|
+
User.destroy_all
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'filter records' do
|
22
|
+
let(:records) { User.all }
|
23
|
+
|
24
|
+
it 'requires a records collection as argument' do
|
25
|
+
expect { datatable.send(:filter_records) }.to raise_error
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'performs a simple search first' do
|
29
|
+
datatable.params[:search] = { value: 'msmith' }
|
30
|
+
expect(datatable).to receive(:build_conditions_for_datatable)
|
31
|
+
datatable.send(:filter_records, records)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'performs a composite search second' do
|
35
|
+
datatable.params[:search] = { value: '' }
|
36
|
+
expect(datatable).to receive(:build_conditions_for_selected_columns)
|
37
|
+
datatable.send(:filter_records, records)
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#build_conditions_for_datatable' do
|
41
|
+
it 'returns an Arel object' do
|
42
|
+
datatable.params[:search] = { value: 'msmith' }
|
43
|
+
result = datatable.send(:build_conditions_for_datatable)
|
44
|
+
expect(result).to be_a(Arel::Nodes::Grouping)
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'no search query' do
|
48
|
+
it 'returns empty query' do
|
49
|
+
datatable.params[:search] = { value: '' }
|
50
|
+
expect(datatable.send(:build_conditions_for_datatable)).to be_blank
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'none of columns are connected' do
|
55
|
+
before(:each) do
|
56
|
+
allow(datatable).to receive(:searchable_columns) { [] }
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'returns empty query result' do
|
60
|
+
datatable.params[:search] = { value: 'msmith' }
|
61
|
+
expect(datatable.send(:build_conditions_for_datatable)).to be_blank
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'with search query' do
|
66
|
+
before(:each) do
|
67
|
+
datatable.params[:search] = { value: "John", regex: "false" }
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'returns a filtering query' do
|
71
|
+
query = datatable.send(:build_conditions_for_datatable)
|
72
|
+
results = records.where(query).map(&:username)
|
73
|
+
expect(results).to include('johndoe')
|
74
|
+
expect(results).not_to include('msmith')
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '#build_conditions_for_selected_columns' do
|
80
|
+
context 'columns include search query' do
|
81
|
+
before do
|
82
|
+
datatable.params[:columns]['0'][:search][:value] = 'doe'
|
83
|
+
datatable.params[:columns]['1'][:search][:value] = 'example'
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'returns an Arel object' do
|
87
|
+
result = datatable.send(:build_conditions_for_selected_columns)
|
88
|
+
expect(result).to be_a(Arel::Nodes::And)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'can call #to_sql on returned object' do
|
92
|
+
result = datatable.send(:build_conditions_for_selected_columns)
|
93
|
+
expect(result).to respond_to(:to_sql)
|
94
|
+
expect(result.to_sql).to eq(
|
95
|
+
"CAST(\"users\".\"username\" AS TEXT) LIKE '%doe%' AND CAST(\"users\".\"email\" AS TEXT) LIKE '%example%'"
|
96
|
+
)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'calls #build_conditions_for_selected_columns' do
|
101
|
+
expect(datatable).to receive(:build_conditions_for_selected_columns)
|
102
|
+
datatable.send(:build_conditions)
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'with search values in columns' do
|
106
|
+
before(:each) do
|
107
|
+
datatable.params[:columns]['0'][:search][:value] = 'doe'
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'returns a filtered set of records' do
|
111
|
+
query = datatable.send(:build_conditions_for_selected_columns)
|
112
|
+
results = records.where(query).map(&:username)
|
113
|
+
expect(results).to include('johndoe')
|
114
|
+
expect(results).not_to include('msmith')
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe '#typecast helper method' do
|
120
|
+
let(:view) { double('view', params: sample_params) }
|
121
|
+
let(:column) { ComplexDatatable.new(view).datatable.columns.first }
|
122
|
+
|
123
|
+
it 'returns VARCHAR if :db_adapter is :pg' do
|
124
|
+
allow_any_instance_of(AjaxDatatablesRails::Configuration).to receive(:db_adapter) { :pg }
|
125
|
+
expect(column.send(:typecast)).to eq('VARCHAR')
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'returns VARCHAR if :db_adapter is :postgre' do
|
129
|
+
allow_any_instance_of(AjaxDatatablesRails::Configuration).to receive(:db_adapter) { :postgre }
|
130
|
+
expect(column.send(:typecast)).to eq('VARCHAR')
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'returns CHAR if :db_adapter is :mysql2' do
|
134
|
+
allow_any_instance_of(AjaxDatatablesRails::Configuration).to receive(:db_adapter) { :mysql2 }
|
135
|
+
expect(column.send(:typecast)).to eq('CHAR')
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'returns CHAR if :db_adapter is :mysql' do
|
139
|
+
allow_any_instance_of(AjaxDatatablesRails::Configuration).to receive(:db_adapter) { :mysql }
|
140
|
+
expect(column.send(:typecast)).to eq('CHAR')
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'returns TEXT if :db_adapter is :sqlite' do
|
144
|
+
allow_any_instance_of(AjaxDatatablesRails::Configuration).to receive(:db_adapter) { :sqlite }
|
145
|
+
expect(column.send(:typecast)).to eq('TEXT')
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'returns TEXT if :db_adapter is :sqlite3' do
|
149
|
+
allow_any_instance_of(AjaxDatatablesRails::Configuration).to receive(:db_adapter) { :sqlite3 }
|
150
|
+
expect(column.send(:typecast)).to eq('TEXT')
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'AjaxDatatablesRails::ORM::ActiveRecord#paginate_records' do
|
4
|
+
let(:view) { double('view', params: sample_params) }
|
5
|
+
let(:datatable) { SampleDatatable.new(view) }
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
AjaxDatatablesRails.configure do |config|
|
9
|
+
config.db_adapter = :sqlite
|
10
|
+
config.orm = :active_record
|
11
|
+
end
|
12
|
+
|
13
|
+
User.create(username: 'johndoe', email: 'johndoe@example.com')
|
14
|
+
User.create(username: 'msmith', email: 'mary.smith@example.com')
|
15
|
+
end
|
16
|
+
|
17
|
+
after(:each) do
|
18
|
+
User.destroy_all
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'paginate records' do
|
22
|
+
let(:records) { User.all }
|
23
|
+
|
24
|
+
it 'requires a records collection argument' do
|
25
|
+
expect { datatable.send(:paginate_records) }.to raise_error
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'paginates records properly' do
|
29
|
+
expect(datatable.send(:paginate_records, records).to_sql).to include(
|
30
|
+
"LIMIT 10 OFFSET 0"
|
31
|
+
)
|
32
|
+
|
33
|
+
datatable.params[:start] = "26"
|
34
|
+
datatable.params[:length] = "25"
|
35
|
+
expect(datatable.send(:paginate_records, records).to_sql).to include(
|
36
|
+
"LIMIT 25 OFFSET 25"
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'depends on the value of #offset' do
|
41
|
+
expect(datatable.datatable).to receive(:offset)
|
42
|
+
datatable.send(:paginate_records, records)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'depends on the value of #per_page' do
|
46
|
+
expect(datatable.datatable).to receive(:per_page).at_least(:once) { 10 }
|
47
|
+
datatable.send(:paginate_records, records)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'AjaxDatatablesRails::ORM::ActiveRecord#sort_records' do
|
4
|
+
let(:view) { double('view', params: sample_params) }
|
5
|
+
let(:datatable) { ComplexDatatable.new(view) }
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
AjaxDatatablesRails.configure do |config|
|
9
|
+
config.db_adapter = :sqlite
|
10
|
+
config.orm = :active_record
|
11
|
+
end
|
12
|
+
|
13
|
+
User.create(username: 'johndoe', email: 'johndoe@example.com')
|
14
|
+
User.create(username: 'msmith', email: 'mary.smith@example.com')
|
15
|
+
end
|
16
|
+
|
17
|
+
after(:each) do
|
18
|
+
User.destroy_all
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'sort records' do
|
22
|
+
let(:records) { User.all }
|
23
|
+
|
24
|
+
it 'returns a records collection sorted by :order params' do
|
25
|
+
# set to order Users by email in descending order
|
26
|
+
datatable.params[:order]['0'] = { column: '1', dir: 'desc' }
|
27
|
+
expect(datatable.send(:sort_records, records).map(&:email)).to match(
|
28
|
+
['mary.smith@example.com', 'johndoe@example.com']
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'can handle multiple sorting columns' do
|
33
|
+
# set to order by Users username in ascending order, and
|
34
|
+
# by Users email in descending order
|
35
|
+
datatable.params[:order]['0'] = { column: '0', dir: 'asc' }
|
36
|
+
datatable.params[:order]['1'] = { column: '1', dir: 'desc' }
|
37
|
+
expect(datatable.send(:sort_records, records).to_sql).to include(
|
38
|
+
"ORDER BY users.username ASC, users.email DESC"
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'AjaxDatatablesRails::ORM::ActiveRecord#fetch_records' do
|
4
|
+
context 'Private API' do
|
5
|
+
let(:view) { double('view', params: sample_params) }
|
6
|
+
let(:datatable) { SampleDatatable.new(view) }
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
AjaxDatatablesRails.configure do |config|
|
10
|
+
config.db_adapter = :sqlite
|
11
|
+
config.orm = :active_record
|
12
|
+
end
|
13
|
+
|
14
|
+
User.create(username: 'johndoe', email: 'johndoe@example.com')
|
15
|
+
User.create(username: 'msmith', email: 'mary.smith@example.com')
|
16
|
+
end
|
17
|
+
|
18
|
+
after(:each) do
|
19
|
+
User.destroy_all
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'fetch records' do
|
23
|
+
it 'calls #get_raw_records' do
|
24
|
+
expect(datatable).to receive(:get_raw_records) { User.all }
|
25
|
+
datatable.send(:fetch_records)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'returns a collection of records' do
|
29
|
+
expect(datatable).to receive(:get_raw_records) { User.all }
|
30
|
+
expect(datatable.send(:fetch_records)).to be_a(ActiveRecord::Relation)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/spec/schema.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
ActiveRecord::Schema.define do
|
2
|
+
self.verbose = false
|
3
|
+
|
4
|
+
create_table :users, :force => true do |t|
|
5
|
+
t.string :username
|
6
|
+
t.string :email
|
7
|
+
t.string :first_name
|
8
|
+
t.string :last_name
|
9
|
+
|
10
|
+
t.timestamps null: false
|
11
|
+
end
|
12
|
+
|
13
|
+
create_table :addresses, :force => true do |t|
|
14
|
+
t.string :address_line1
|
15
|
+
t.string :address_line2
|
16
|
+
t.string :city
|
17
|
+
t.string :zip_code
|
18
|
+
t.string :state
|
19
|
+
t.string :country
|
20
|
+
|
21
|
+
t.timestamps null: false
|
22
|
+
end
|
23
|
+
|
24
|
+
create_table :purchased_orders, :force => true do |t|
|
25
|
+
t.string :foo
|
26
|
+
t.string :bar
|
27
|
+
|
28
|
+
t.timestamps null: false
|
29
|
+
end
|
30
|
+
|
31
|
+
create_table :statistics_requests, :force => true do |t|
|
32
|
+
t.string :baz
|
33
|
+
|
34
|
+
t.timestamps null: false
|
35
|
+
end
|
36
|
+
|
37
|
+
create_table :statistics_sessions, :force => true do |t|
|
38
|
+
t.string :foo
|
39
|
+
t.integer :bar
|
40
|
+
|
41
|
+
t.timestamps null: false
|
42
|
+
end
|
43
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'pry'
|
2
|
+
require 'rails'
|
3
|
+
require 'active_record'
|
4
|
+
require 'ajax-datatables-rails'
|
5
|
+
|
6
|
+
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
|
7
|
+
|
8
|
+
load File.dirname(__FILE__) + '/schema.rb'
|
9
|
+
load File.dirname(__FILE__) + '/test_helpers.rb'
|
10
|
+
require File.dirname(__FILE__) + '/test_models.rb'
|
@@ -0,0 +1,66 @@
|
|
1
|
+
def sample_params
|
2
|
+
ActiveSupport::HashWithIndifferentAccess.new(
|
3
|
+
{
|
4
|
+
"draw"=>"1",
|
5
|
+
"columns"=> {
|
6
|
+
"0"=> {
|
7
|
+
"data"=>"username", "name"=>"", "searchable"=>"true", "orderable"=>"true",
|
8
|
+
"search"=> {
|
9
|
+
"value"=>"", "regex"=>"false"
|
10
|
+
}
|
11
|
+
},
|
12
|
+
"1"=> {
|
13
|
+
"data"=>"email", "name"=>"", "searchable"=>"true", "orderable"=>"true",
|
14
|
+
"search"=> {
|
15
|
+
"value"=>"", "regex"=>"false"
|
16
|
+
}
|
17
|
+
},
|
18
|
+
"2"=> {
|
19
|
+
"data"=>"first_name", "name"=>"", "searchable"=>"false", "orderable"=>"false",
|
20
|
+
"search"=> {
|
21
|
+
"value"=>"", "regex"=>"false"
|
22
|
+
}
|
23
|
+
},
|
24
|
+
"3"=> {
|
25
|
+
"data"=>"last_name", "name"=>"", "searchable"=>"false", "orderable"=>"true",
|
26
|
+
"search"=> {
|
27
|
+
"value"=>"", "regex"=>"false"
|
28
|
+
}
|
29
|
+
},
|
30
|
+
},
|
31
|
+
"order"=> {
|
32
|
+
"0"=> {"column"=>"0", "dir"=>"asc"}
|
33
|
+
},
|
34
|
+
"start"=>"0", "length"=>"10", "search"=>{
|
35
|
+
"value"=>"", "regex"=>"false"
|
36
|
+
},
|
37
|
+
"_"=>"1423364387185"
|
38
|
+
}
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
class SampleDatatable < AjaxDatatablesRails::Base
|
43
|
+
def view_columns
|
44
|
+
@view_columns ||= ['User.username', 'User.email', 'User.first_name', 'User.last_name']
|
45
|
+
end
|
46
|
+
|
47
|
+
def data
|
48
|
+
[{}, {}]
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_raw_records
|
52
|
+
User.all
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
class ComplexDatatable < SampleDatatable
|
58
|
+
def view_columns
|
59
|
+
@view_columns ||= {
|
60
|
+
username: { source: 'User.username' },
|
61
|
+
email: { source: 'User.email' },
|
62
|
+
first_name: { source: 'User.first_name' },
|
63
|
+
last_name: { source: 'User.last_name' }
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
data/spec/test_models.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
class User < ActiveRecord::Base
|
2
|
+
end
|
3
|
+
|
4
|
+
class Address < ActiveRecord::Base
|
5
|
+
end
|
6
|
+
|
7
|
+
class PurchasedOrder < ActiveRecord::Base
|
8
|
+
end
|
9
|
+
|
10
|
+
module Statistics
|
11
|
+
def self.table_name_prefix
|
12
|
+
"statistics_"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Statistics::Request < ActiveRecord::Base
|
17
|
+
end
|
18
|
+
|
19
|
+
class Statistics::Session < ActiveRecord::Base
|
20
|
+
end
|