rails-tables 0.5.1 → 0.6.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.
- data/README.md +1 -1
- data/app/tables/column.rb +11 -9
- data/app/tables/datatable.rb +13 -13
- data/app/tables/datatable/searching.rb +5 -2
- data/app/tables/datatable/sorting.rb +1 -0
- data/lib/rails-tables.rb +2 -0
- data/lib/rails-tables/exceptions.rb +3 -0
- data/lib/rails-tables/model_additions.rb +49 -7
- data/lib/rails-tables/relation_additions.rb +25 -0
- data/lib/rails-tables/version.rb +1 -1
- metadata +4 -2
data/README.md
CHANGED
@@ -12,7 +12,7 @@ A clean jQuery datatables DSL
|
|
12
12
|
[jqd-railscast]: http://railscasts.com/episodes/340-datatables (Episode #340: Datatables)
|
13
13
|
[squeel]: https://github.com/ernie/squeel (Squeel: ActiveRecord 3, improved)
|
14
14
|
|
15
|
-
Version: 0.
|
15
|
+
Version: 0.6.0
|
16
16
|
|
17
17
|
Please refer to the [RailsTables Wiki][wiki] for:
|
18
18
|
|
data/app/tables/column.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
class Column
|
2
2
|
|
3
|
-
attr_accessor :model, :name, :method, :column_source, :render_with, :blank_value, :virtual, :sortable, :searchable
|
3
|
+
attr_accessor :table_name, :model, :name, :method, :column_source, :render_with, :blank_value, :virtual, :sortable, :searchable
|
4
4
|
|
5
|
-
def initialize(model, name, *args)
|
5
|
+
def initialize(table_name, model, name, *args)
|
6
|
+
self.table_name = table_name
|
6
7
|
self.model = model
|
7
|
-
self.name = name
|
8
|
+
self.name = name
|
8
9
|
|
9
10
|
attributes = args.pop || {}
|
10
11
|
self.method = attributes.fetch(:method, name).to_s
|
@@ -15,7 +16,12 @@ class Column
|
|
15
16
|
self.sortable = attributes.fetch(:sortable, !self.virtual)
|
16
17
|
self.searchable = attributes.fetch(:searchable, !self.virtual)
|
17
18
|
|
18
|
-
|
19
|
+
if virtual and not attributes.has_key?(:render_with)
|
20
|
+
raise Exception,
|
21
|
+
"Virtual columns are required to supply a render method (render_with: lambda): "\
|
22
|
+
"Column: #{self.name}, Datatable: #{self.table_name}, Model: #{self.model.name}"
|
23
|
+
end
|
24
|
+
|
19
25
|
self.render_with = attributes.fetch(:render_with, :default_render)
|
20
26
|
self.blank_value = attributes.fetch(:blank_value, '–')
|
21
27
|
|
@@ -49,15 +55,11 @@ private
|
|
49
55
|
end
|
50
56
|
def related_link(view, object)
|
51
57
|
property = object.try(:send, self.method)
|
52
|
-
view.link_to property,
|
58
|
+
view.link_to property, object if not property.nil?
|
53
59
|
end
|
54
60
|
def related_link_list(view, objects)
|
55
61
|
objects.reject(&:blank?).map{ |object| related_link(view, object).strip }.join(', ') if not objects.nil?
|
56
62
|
end
|
57
|
-
# def unique_related_link_list(view, objects, field)
|
58
|
-
# binding.pry if objects.length > 1
|
59
|
-
# related_link_list(view, objects.uniq{|o| o.send(field)} )
|
60
|
-
# end
|
61
63
|
def time(view, object)
|
62
64
|
property = object.try(:send, self.method)
|
63
65
|
property.strftime("%I:%M%p") if not property.nil?
|
data/app/tables/datatable.rb
CHANGED
@@ -3,12 +3,17 @@ class Datatable
|
|
3
3
|
include Datatable::Searching
|
4
4
|
delegate :params, to: 'self.view'
|
5
5
|
|
6
|
-
attr_accessor :name, :
|
6
|
+
attr_accessor :name, :root, :model, :view
|
7
7
|
|
8
|
-
# Called in has_datatable for model
|
8
|
+
# Called in has_datatable for model, or on an ActiveRecord::Relation in method_missing
|
9
9
|
def initialize(name, model)
|
10
10
|
self.name = name
|
11
|
-
self.model = model
|
11
|
+
self.root = self.model = model
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_root(root)
|
15
|
+
self.root = root
|
16
|
+
self
|
12
17
|
end
|
13
18
|
|
14
19
|
# Render data attributes for table for view
|
@@ -27,10 +32,8 @@ class Datatable
|
|
27
32
|
end
|
28
33
|
|
29
34
|
# Pass in view and scope table for controller
|
30
|
-
def render_with(view
|
31
|
-
arguments = args.pop || {}
|
35
|
+
def render_with(view)
|
32
36
|
self.view = view
|
33
|
-
self.scopes = Array(arguments.fetch(:scopes, []))
|
34
37
|
return self
|
35
38
|
end
|
36
39
|
|
@@ -54,15 +57,15 @@ class Datatable
|
|
54
57
|
end
|
55
58
|
|
56
59
|
class_attribute :columns, :column_factory
|
57
|
-
# Allow user defined columns, lazily instanciate later after 'self.
|
60
|
+
# Allow user defined columns, lazily instanciate later after 'self.root' is defined
|
58
61
|
def self.column(name, *args)
|
59
62
|
arguments = args.pop || {}
|
60
63
|
self.column_factory = [] if self.column_factory.nil?
|
61
|
-
self.column_factory << { name: name, args: arguments }
|
64
|
+
self.column_factory << { name: name.to_s, args: arguments }
|
62
65
|
end
|
63
66
|
# Lazily instanciates and caches columns
|
64
67
|
def columns
|
65
|
-
@columns ||= self.column_factory.map{ |new_column| Column.new(self.model, new_column[:name], new_column[:args]) }
|
68
|
+
@columns ||= self.column_factory.map{ |new_column| Column.new(self.class.name, self.model, new_column[:name], new_column[:args]) }
|
66
69
|
end
|
67
70
|
|
68
71
|
class_attribute :joins
|
@@ -80,14 +83,11 @@ private
|
|
80
83
|
|
81
84
|
# Compose query to fetch objects from database
|
82
85
|
def objects
|
83
|
-
query = self.
|
86
|
+
query = self.root.uniq
|
84
87
|
self.joins.each do |join|
|
85
88
|
query = query.joins{ join.split('.').inject((join.present? ? self : nil), :__send__).outer }
|
86
89
|
query = query.includes{ join.split('.').inject((join.present? ? self : nil), :__send__).outer }
|
87
90
|
end
|
88
|
-
self.scopes.each do |scope|
|
89
|
-
query = scope.call(query)
|
90
|
-
end
|
91
91
|
query = query.reorder{ my{sort} } if sortable
|
92
92
|
query = query.where{ my{search(params[:sSearch])} } if searchable
|
93
93
|
query = query.paginate(page: page, per_page: per_page)
|
@@ -17,8 +17,11 @@ module Datatable::Searching
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
# InstanceMethods
|
21
|
+
attr_accessor :searches
|
22
|
+
|
21
23
|
private
|
24
|
+
|
22
25
|
def searchable
|
23
26
|
params[:sSearch].present?
|
24
27
|
end
|
@@ -33,7 +36,7 @@ private
|
|
33
36
|
# Build Squeel Stubs for search
|
34
37
|
def search(terms)
|
35
38
|
terms = terms.split if terms.is_a? String
|
36
|
-
|
39
|
+
@searches.map do |search|
|
37
40
|
terms.map do |word|
|
38
41
|
Squeel::Nodes::KeyPath.new(search[:column_source].split('.') << Squeel::Nodes::Stub.new(search[:method])) =~ "%#{word}%"
|
39
42
|
end.compact.inject(&:|)
|
data/lib/rails-tables.rb
CHANGED
@@ -1,11 +1,53 @@
|
|
1
1
|
module RailsTables::ModelAdditions
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
def has_datatable(*args)
|
11
|
+
arguments = { }
|
12
|
+
if args.present?
|
13
|
+
if args.first.is_a? Hash
|
14
|
+
arguments = args.pop
|
15
|
+
else
|
16
|
+
arguments[:name] = args.first if args.try(:first)
|
17
|
+
arguments[:klass] = args.second if args.try(:second)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
name = arguments.fetch(:name, 'datatable').to_s
|
21
|
+
klass = arguments.fetch(:klass, "#{self.name.pluralize.underscore}_datatable").to_s.camelize
|
22
|
+
klass = klass.constantize
|
23
|
+
|
24
|
+
cattr_accessor :datatables unless self.respond_to? :datatables
|
25
|
+
self.datatables ||= {}
|
26
|
+
|
27
|
+
if self.has_datatable? name
|
28
|
+
raise RailsTables::NameError,
|
29
|
+
"#{self.name} already has a datatable with the name '#{name}'. "\
|
30
|
+
"Please supply a :name parameter to has_datatable other than: #{self.datatables.keys.join(', ')}"
|
31
|
+
else
|
32
|
+
self.datatables[name] = klass
|
33
|
+
cattr_writer name
|
34
|
+
self.send("#{name}=", klass.new(name, self))
|
35
|
+
self.class.instance_eval do
|
36
|
+
define_method name do
|
37
|
+
self.class_variable_get("@@#{name}").set_root(self)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def has_datatable?(table_name=:datatable)
|
44
|
+
self.respond_to? :datatables and self.datatables.keys.include? table_name.to_s
|
45
|
+
end
|
46
|
+
|
8
47
|
end
|
48
|
+
|
49
|
+
# InstanceMethods
|
50
|
+
|
9
51
|
end
|
10
52
|
|
11
|
-
ActiveRecord::Base.
|
53
|
+
ActiveRecord::Base.send :include, RailsTables::ModelAdditions
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RailsTables::RelationAdditions
|
2
|
+
|
3
|
+
delegate :has_datatable?, to: :klass
|
4
|
+
|
5
|
+
def respond_to?(method, include_private = false)
|
6
|
+
if self.has_datatable? method.to_s
|
7
|
+
true
|
8
|
+
else
|
9
|
+
super
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def method_missing(method, *args, &block)
|
16
|
+
if self.has_datatable? method.to_s
|
17
|
+
self.klass.send(method.to_s).set_root(self)
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
ActiveRecord::Relation.send :include, RailsTables::RelationAdditions
|
data/lib/rails-tables/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-tables
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -122,7 +122,9 @@ files:
|
|
122
122
|
- app/tables/datatable.rb
|
123
123
|
- config/routes.rb
|
124
124
|
- lib/rails-tables/engine.rb
|
125
|
+
- lib/rails-tables/exceptions.rb
|
125
126
|
- lib/rails-tables/model_additions.rb
|
127
|
+
- lib/rails-tables/relation_additions.rb
|
126
128
|
- lib/rails-tables/version.rb
|
127
129
|
- lib/rails-tables.rb
|
128
130
|
- lib/tasks/rails-tables_tasks.rake
|