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 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.5.1
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.to_s
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
- raise Exception, "Virtual columns are required to supply a render method (render_with: lambda): Column #{self.name}, Model: #{self.model.name}" if virtual and not attributes.has_key?(:render_with)
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, property if not property.nil?
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?
@@ -3,12 +3,17 @@ class Datatable
3
3
  include Datatable::Searching
4
4
  delegate :params, to: 'self.view'
5
5
 
6
- attr_accessor :name, :model, :view, :scopes
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, *args)
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.model' is defined
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.model.uniq
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
- attr_accessor :searches
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
- searchables.map do |search|
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(&:|)
@@ -18,6 +18,7 @@ module Datatable::Sorting
18
18
 
19
19
  end
20
20
 
21
+ # InstanceMethods
21
22
  private
22
23
  # Check if table is sortable
23
24
  def sortable
data/lib/rails-tables.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require "rails-tables/engine"
2
+ require "rails-tables/exceptions"
2
3
  require "rails-tables/model_additions"
4
+ require "rails-tables/relation_additions"
3
5
 
4
6
  module RailsTables
5
7
  end
@@ -0,0 +1,3 @@
1
+ module RailsTables
2
+ class NameError < ::NameError; end
3
+ end
@@ -1,11 +1,53 @@
1
1
  module RailsTables::ModelAdditions
2
- def has_datatable(*args)
3
- arguments = args.pop || {}
4
- name = arguments.fetch(:name, 'datatable')
5
- klass = arguments.fetch(:klass, "#{self.name.pluralize.underscore}_datatable").camelize
6
- cattr_accessor name
7
- self.send("#{name}=", klass.constantize.new(name, self))
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.extend RailsTables::ModelAdditions
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
@@ -1,3 +1,3 @@
1
1
  module RailsTables
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
3
3
  end
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.5.1
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-11-30 00:00:00.000000000 Z
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