rails-tables 0.1.0 → 0.2.1

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.
@@ -1,4 +1,4 @@
1
- Copyright 2012 YOURNAME
1
+ Copyright 2012 CHRISTOPHER KEELE
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,13 +1,21 @@
1
1
  class Datatable
2
2
  delegate :params, to: 'self.view'
3
-
4
- attr_accessor :view, :filters
5
- def initialize(view, filters={})
3
+
4
+ attr_accessor :name, :model
5
+ def initialize(name, model)
6
+ self.name = name
7
+ self.model = model
8
+ end
9
+
10
+ attr_accessor :view, :filters
11
+ def render_with(view, *args)
12
+ arguments = args.pop || {}
6
13
  self.view = view
7
- self.filters = filters
14
+ self.filters = arguments.fetch(:filters, {})
15
+ return self
8
16
  end
9
17
 
10
- def as_json(options = {})
18
+ def as_json(options={})
11
19
  {
12
20
  sEcho: params[:sEcho].to_i,
13
21
  iTotalRecords: objects.size,
@@ -16,41 +24,43 @@ class Datatable
16
24
  }
17
25
  end
18
26
 
19
- class << self
20
- attr_accessor :columns, :searches
21
- def column(name, *args)
22
- arguments = args.pop || {}
23
- self.columns = [] if self.columns.nil?
24
- self.columns << Column.new(name, arguments)
25
- end
26
- # def search_by(name, *args)
27
- # arguments = args.pop || {}
28
- # self.searches = [] if self.searches.nil?
29
- # self.searches << Search.new(name, self.table, arguments)
30
- # end
27
+ class_attribute :columns, :searches, :match_any
28
+ def self.column(name, *args)
29
+ arguments = args.pop || {}
30
+ self.columns = [] if self.columns.nil?
31
+ self.columns << Column.new(name, arguments)
32
+ end
33
+ def self.search_by(name, *args)
34
+ arguments = args.pop || {}
35
+ self.searches = [] if self.searches.nil?
36
+ self.searches << Search.new(name, self, arguments)
37
+ end
38
+ self.match_any = true
39
+ def self.match_any_column(match_any=true)
40
+ self.match_any = match_any
31
41
  end
32
42
 
33
43
  private
34
44
 
35
45
  def objects
36
46
  if sortable
37
- objects = self.class.model.reorder("#{sort_column} #{sort_direction}")
47
+ objects = self.model.reorder("#{sort_column} #{sort_direction}")
38
48
  else
39
- objects = self.class.model
49
+ objects = self.model
40
50
  end
41
51
  @filters.each do |method, arguments|
42
52
  objects = objects.send(method, arguments)
43
53
  end
44
- # if params[:sSearch].present?
45
- # objects = self.model(:datatable_search, search(objects, params[:sSearch]))
46
- # #objects = objects.where("name like :search or category like :search", search: "%#{params[:sSearch]}%")
47
- # end
54
+ if params[:sSearch].present?
55
+ objects = objects.send("#{self.name}_search", params[:sSearch])
56
+ #objects = objects.where("name like :search or category like :search", search: "%#{params[:sSearch]}%")
57
+ end
48
58
  objects = objects.paginate(page: page, per_page: per_page)
49
59
  objects
50
60
  end
51
61
 
52
62
  def search(objects, terms)
53
- self.class.searches.each do |search|
63
+ self.searches.each do |search|
54
64
  objects = search.search(objects, terms)
55
65
  end
56
66
  end
@@ -63,10 +73,10 @@ private
63
73
  end
64
74
 
65
75
  def sortable
66
- self.class.columns.map{ |column| column.sortable }[params[:iSortCol_0].to_i]
76
+ self.columns.map{ |column| column.sortable }[params[:iSortCol_0].to_i]
67
77
  end
68
78
  def sort_column
69
- self.class.columns.map(&:column_name)[params[:iSortCol_0].to_i]
79
+ self.columns.map(&:column_name)[params[:iSortCol_0].to_i]
70
80
  end
71
81
  def sort_direction
72
82
  params[:sSortDir_0] == "desc" ? "desc" : "asc"
@@ -74,7 +84,7 @@ private
74
84
 
75
85
  def data
76
86
  objects.map do |object|
77
- self.class.columns.map{ |column| column.render(self.view, object) }
87
+ self.columns.map{ |column| column.render(self.view, object) }
78
88
  end
79
89
  end
80
90
 
@@ -1,68 +1,56 @@
1
1
  class Search
2
-
3
- attr_accessor :name, :table, :column_name, :search_with
2
+ cattr_accessor :strategies
3
+ self.strategies = {
4
+ contains_strategy: {
5
+ type: :string,
6
+ match_with: '%%%s%%'
7
+ },
8
+ starts_with_strategy: {
9
+ type: :string,
10
+ match_with: '%s%%'
11
+ },
12
+ ends_with_strategy: {
13
+ type: :string,
14
+ match_with: '%%%s'
15
+ }
16
+ }
17
+ attr_accessor :name, :table, :column_name, :search_with, :match_any, :split_terms
4
18
  def initialize(name, table, *args)
5
19
  self.name = name
6
20
  self.table = table
7
21
 
8
22
  attributes = args.pop || {}
9
23
  self.column_name = attributes.fetch(:column_name, name)
10
- self.search_with = attributes.fetch(:strategy, :default_strategy)
24
+ self.search_with = attributes.fetch(:search_with, :contains_strategy)
25
+ self.match_any = attributes.fetch(:match_any, true)
26
+ self.split_terms = attributes.fetch(:split_terms, true)
11
27
 
12
28
 
13
- define_singleton_method :search do |objects, terms|
29
+ define_singleton_method :search do
14
30
  if self.search_with.kind_of? Symbol
15
- self.send(self.search_with, self.column_name, objects, terms)
31
+ strategy_builder(self.search_with, self.match_any, self.split_terms)
16
32
  else
17
- self.search_with.call(self.column_name, objects, terms)
33
+ self.search_with(self.match_any, self.split_terms)
18
34
  end
19
35
  end
20
36
  end
21
37
 
22
- def default_strategy(field, objects, terms)
23
- self.starts_with_strategy(field, objects, terms)
24
- end
25
- def starts_with_strategy(field, objects, terms)
26
- terms.split.map{|s| s+="%"}.map do |term|
27
- Squeel::Nodes::Predicate.new(Squeel::Nodes::Stub.new(field), :matches, term)
28
- end.inject do |t, expr|
29
- t | expr
30
- end.tap do |block|
31
- return objects.where{block}
32
- end
33
- end
34
- def contains_strategy(field, objects, terms)
35
- terms.split.map{|s| s="%#{s}%"}.map do |term|
36
- Squeel::Nodes::Predicate.new(Squeel::Nodes::Stub.new(field), :matches, term)
37
- end.inject do |t, expr|
38
- t | expr
39
- end.tap do |block|
40
- return objects.where{block}
38
+ def strategy_builder(strategy_name, match_any, split_terms)
39
+ Proc.new do |field, terms|
40
+ if split_terms
41
+ terms = terms.split
42
+ else
43
+ terms = [terms]
44
+ end
45
+ terms.map{|s| Search.strategies[strategy_name][:match_with] % s}.map do |term|
46
+ Squeel::Nodes::Predicate.new(Squeel::Nodes::Stub.new(field), :matches, term)
47
+ end.inject do |t, expr|
48
+ if match_any
49
+ t | expr
50
+ else
51
+ t & expr
52
+ end
53
+ end
41
54
  end
42
55
  end
43
- # def self_referential_link(view, object)
44
- # property = object.send(self.column_name)
45
- # view.link_to property, object if not property.nil?
46
- # end
47
- # def related_link(view, object)
48
- # property = object.send(self.column_name)
49
- # view.link_to self.name, property if not property.nil?
50
- # end
51
- # def related_link_list(view, object)
52
- # property = object.send(self.referring_column_name)
53
- # property.collect { |related_object| self_referential_link(view, related_object) }.join(', ') if not property.nil?
54
- # end
55
- # def time(view, object)
56
- # property = object.send(self.column_name)
57
- # property.strftime("%I:%M%p") if not property.nil?
58
- # end
59
- # def date(view, object)
60
- # property = object.send(self.column_name)
61
- # property.strftime("%m/%d/%Y") if not property.nil?
62
- # end
63
- # def datetime(view, object)
64
- # property = object.send(self.column_name)
65
- # property.strftime("%m/%d/%Y at %I:%M%p") if not property.nil?
66
- # end
67
-
68
56
  end
@@ -1,13 +1,22 @@
1
1
  def has_datatable(*args)
2
2
  arguments = args.pop || {}
3
3
  name = arguments.fetch(:name, 'datatable')
4
- klass = arguments.fetch(:klass, "#{self.name.pluralize}Table")
5
- require File.join(Rails.root, 'app', 'tables', "#{klass.underscore}.rb")
6
- model = self
7
- klass.constantize.class.send(:define_method, 'model') do
8
- model
4
+ klass = arguments.fetch(:klass, "#{self.name.pluralize}Datatable")
5
+ cattr_accessor name
6
+ self.send("#{name}=", klass.constantize.new(name, self))
7
+ self.class.instance_eval do
8
+ define_method "#{name}_search" do |terms|
9
+ searches =
10
+ self.datatable.searches.map do |search|
11
+ self.instance_exec search.column_name, terms, &search.search
12
+ end.inject do |t, expr|
13
+ if self.datatable.match_any
14
+ t | expr
15
+ else
16
+ t & expr
17
+ end
18
+ end
19
+ self.where{ searches }
20
+ end
9
21
  end
10
- self.class.send(:define_method, name) do
11
- klass.constantize
12
- end
13
- end
22
+ end
@@ -1,3 +1,3 @@
1
1
  module RailsTables
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.1"
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.1.0
4
+ version: 0.2.1
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-08-27 00:00:00.000000000 Z
12
+ date: 2012-09-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails