Skip to content

Commit 405c331

Browse files
author
M. Saiqul Haq
committed
add set_model_class method for setup custom model class name
1 parent a297e4a commit 405c331

File tree

10 files changed

+124
-21
lines changed

10 files changed

+124
-21
lines changed

README.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ end
8787
* For `paginator options`, just uncomment the paginator you would like to use, given
8888
the gems bundled in your project. For example, if your models are using `Kaminari`, uncomment `AjaxDatatablesRails::Extensions::Kaminari`. You may remove all commented lines.
8989
* `SimplePaginator` is the most basic of them all, it falls back to passing `offset` and `limit` at the database level (through `ActiveRecord` of course, as that is the only ORM supported for the time being).
90-
9190
* 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.
9291

9392
* For `searchable_columns`, assign an array of the database columns that you want searchable by datatables. For example `[users.f_name, users.l_name]`
@@ -230,6 +229,39 @@ So the query using the `.includes()` method is:
230229
end
231230
```
232231

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

ajax-datatables-rails.gemspec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@ Gem::Specification.new do |gem|
2424
gem.add_development_dependency "generator_spec"
2525
gem.add_development_dependency "pry"
2626
gem.add_development_dependency "rake"
27-
gem.add_development_dependency "activerecord", "~> 4.l.6"
2827
gem.add_development_dependency "sqlite3"
2928

3029
if RUBY_VERSION == '1.9.2'
3130
gem.add_development_dependency "rails", "3.1.0"
31+
gem.add_development_dependency "activerecord", "3.1.0"
3232
else
3333
gem.add_development_dependency "rails", ">= 3.1.0"
34+
gem.add_development_dependency "activerecord", ">= 4.1.6"
3435
end
3536
end

lib/ajax-datatables-rails.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
require 'ajax-datatables-rails/version'
22
require 'ajax-datatables-rails/config'
3+
require 'ajax-datatables-rails/models'
34
require 'ajax-datatables-rails/base'
45
require 'ajax-datatables-rails/extensions/simple_paginator'
56
require 'ajax-datatables-rails/extensions/kaminari'

lib/ajax-datatables-rails/base.rb

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ 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
1225
end
1326

1427
def config
@@ -104,13 +117,11 @@ def build_conditions_for(query)
104117

105118
def search_condition(column, value)
106119
model, column = column.split('.')
107-
if model.scan("_").any?
108-
model = model.singularize.titleize.gsub( / /, '::' ).constantize
109-
else
110-
model = model.singularize.titleize.gsub( / /, '' ).constantize
111-
end
120+
model_class = model.singularize.titleize.gsub( / /, '' ).safe_constantize
121+
model_class = models[model] if model_class.nil?
122+
raise("Model with class name #{model} not found") if model_class.nil?
112123

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

lib/ajax-datatables-rails/models.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
require 'active_support/ordered_options'
2+
3+
module AjaxDatatablesRails
4+
class Models < ActiveSupport::OrderedOptions
5+
end
6+
end

spec/ajax-datatables-rails/ajax_datatables_rails_spec.rb

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -120,25 +120,57 @@
120120
end
121121
end
122122

123-
describe "#search_condition" do
124-
let(:datatable) { AjaxDatatablesRails::Base.new(view) }
123+
describe "#configure" do
124+
let(:datatable) do
125+
class FooDatatable < AjaxDatatablesRails::Base
126+
def setup
127+
set_model_class do |klass|
128+
klass.users = User
129+
klass.requests = Statistics::Request
130+
klass.purchased_orders = PurchasedOrder
131+
klass.statistics_sessions = Statistics::Session
132+
end
133+
end
134+
end
135+
136+
FooDatatable.new view
137+
end
125138

126-
context "normal model" do
127-
it "should return arel object" do
128-
expect(datatable.send(:search_condition, 'users.bar', 'bar').class).to eq(Arel::Nodes::Matches)
139+
context "when model class name is regular" do
140+
it "should successfully get right model class" do
141+
datatable.send(:search_condition, 'users.bar', 'bar')
142+
expect(datatable.models.users).to eq(User)
129143
end
130144
end
131145

132-
context "namespaced model" do
133-
it "should return arel object" do
134-
expect(datatable.send(:search_condition, 'statistics_sessions.bar', 'bar').class).to eq(Arel::Nodes::Matches)
146+
context "when custom named model class" do
147+
it "should successfully get right model class" do
148+
expect(datatable.send(:search_condition, 'requests.bar', 'bar').class)
149+
.to eq(Arel::Nodes::Matches)
135150
end
136151
end
137152

138-
it "should raise uninitialized constant if column not exist" do
139-
expect {
140-
datatable.send(:search_condition, 'asdusers.bar', 'bar').class
141-
}.to raise_error(/uninitialized constant/)
153+
154+
context "when model class name camelcased" do
155+
it "should successfully get right model class" do
156+
expect(datatable.send(:search_condition, 'purchased_orders.bar', 'bar').class)
157+
.to eq(Arel::Nodes::Matches)
158+
end
159+
end
160+
161+
context "when model class name is namespaced" do
162+
it "should successfully get right model class" do
163+
expect(datatable.send(:search_condition, 'statistics_sessions.bar', 'bar').class)
164+
.to eq(Arel::Nodes::Matches)
165+
end
166+
end
167+
168+
context "when model class defined but not found" do
169+
it "raise 'uninitialized constant'" do
170+
expect {
171+
datatable.send(:search_condition, 'non_existed_model.bar', 'bar')
172+
}.to raise_error(RuntimeError, /not found/)
173+
end
142174
end
143175
end
144176

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
require 'spec_helper'
2+
3+
describe AjaxDatatablesRails::Models do
4+
let(:models){ AjaxDatatablesRails::Models.new }
5+
6+
it "is configurable" do
7+
models.user = User
8+
expect(models.user).to eq(User)
9+
end
10+
end

spec/schema.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
t.timestamps
1414
end
1515

16+
create_table :purchased_orders, :force => true do |t|
17+
t.string :foo
18+
t.string :bar
19+
20+
t.timestamps
21+
end
1622

1723
create_table :statistics_requests, :force => true do |t|
1824
t.string :baz

spec/spec_helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
77

88
load File.dirname(__FILE__) + '/schema.rb'
9-
require File.dirname(__FILE__) + '/models.rb'
9+
require File.dirname(__FILE__) + '/test_models.rb'

spec/models.rb renamed to spec/test_models.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ class User < ActiveRecord::Base
22
end
33

44
class UserData < ActiveRecord::Base
5+
self.table_name = "user_data"
6+
end
7+
8+
class PurchasedOrder < ActiveRecord::Base
59
end
610

711
module Statistics

0 commit comments

Comments
 (0)