fancy_table 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: af8f0bf6693d73534a20a72de346b66a565f53b1
4
+ data.tar.gz: 20fb9121bcf4e0a0a9d2e1719d4806ad263a8115
5
+ SHA512:
6
+ metadata.gz: 8ba17365f8f49b29810a50a77f96dde6085fb23def04cab9f720eae8726a7844f929550b420c6434a4e77ad70647782fc160e6bc9e26aa3a80a4a82f5759cc8b
7
+ data.tar.gz: 80614f7eb65e847abc2466113ffe9b3276cd9cc33b309f6b94b9a9991dbdf76fca943f10181f69b28b0b86a7bce9a9e88d97cb0b9b1a27a66dbe3e7f2622cc6a
@@ -0,0 +1,16 @@
1
+ require "fancy_table/version"
2
+ require 'haml'
3
+ require 'smart_order'
4
+ require 'sass-rails'
5
+ require 'map_hash'
6
+ require 'squeel'
7
+ require 'kaminari'
8
+ require 'coffee-filter'
9
+ require 'fancy_table/view_helpers'
10
+ require 'fancy_table/controller_methods'
11
+ require 'fancy_table/railtie' if defined?(Rails)
12
+
13
+
14
+ module FancyTable
15
+ # Your code goes here...
16
+ end
@@ -0,0 +1,29 @@
1
+ class ActionController::Base
2
+ def fancy_table(objects, options = {})
3
+ order = options[:order] || params[:order_by]
4
+ objects.define_singleton_method(:fancy_table_order) { order }
5
+ klass = objects.first.class
6
+
7
+ headers = options[:headers] ||
8
+ begin
9
+ names = klass.column_names - %w{id created_at updated_at}
10
+ names.map { |name| name.sub(/_id$/, '') }.map_hash{ |name| [name, name.titleize] }
11
+ end
12
+
13
+ objects.define_singleton_method(:fancy_table_headers) { headers }
14
+
15
+ if order =~ /\A(#{headers.keys.join('|')})( desc)?\Z/
16
+ objects=objects.smart_order order
17
+ end
18
+
19
+ page = options[:page] || params[:page]
20
+ limit = options[:limit]
21
+ if limit || page
22
+ page ||= 1
23
+ objects = objects.page(page.to_i)
24
+ objects = objects.per(limit) if limit
25
+ end
26
+
27
+ objects
28
+ end
29
+ end
@@ -0,0 +1,12 @@
1
+ module FancyTable
2
+ class Railtie < Rails::Railtie
3
+ config.before_configuration do |app|
4
+ app.paths['app/views'] << File.expand_path('../../../app/views', __FILE__)
5
+ app.paths['app/assets'] << File.expand_path('../../../app/assets', __FILE__)
6
+ end
7
+
8
+ initializer "fancy_table.view_helpers" do
9
+ ActionView::Base.send :include, ViewHelpers
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module FancyTable
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,34 @@
1
+ module FancyTable
2
+ module ViewHelpers
3
+ def wrap_if(condition, symbol, *args, &block)
4
+ if condition
5
+ send symbol, *args, &block
6
+ else
7
+ capture(&block)
8
+ end
9
+ end
10
+
11
+ def wrap_unless(condition, symbol, *args, &block)
12
+ wrap_if(!condition, symbol, *args, &block)
13
+ end
14
+
15
+ def link_to_object(object, label_attribute = nil)
16
+ if object.class.respond_to? :table_name
17
+ pathmethod = "#{object.class.table_name.singularize}_path"
18
+ if respond_to? pathmethod
19
+ link_to object.send( label_attribute || object.class.default_order_column ), send(pathmethod, object)
20
+ else
21
+ object.to_s
22
+ end
23
+ else
24
+ object.to_s
25
+ end
26
+ end
27
+
28
+ def fancy_table(objects, options = {})
29
+ options.merge! objects: objects
30
+ render partial: 'fancy_table/fancy_table', locals: options
31
+ end
32
+ end
33
+ end
34
+
data/lib/map_hash.rb ADDED
@@ -0,0 +1,18 @@
1
+ module Enumerable
2
+ def map_hash(&block)
3
+ inject({}) do |memo, *args|
4
+ results = block.call(*args)
5
+ unless results.nil?
6
+ k, v = results
7
+ memo[k]=v
8
+ end
9
+ memo
10
+ end
11
+ end
12
+
13
+ def slice_hash
14
+ hash={}
15
+ each_slice(2) { |k,v| hash[k]=v }
16
+ hash
17
+ end
18
+ end
@@ -0,0 +1,71 @@
1
+ class ActiveRecord::Base
2
+ def self.smart_order(order, desc = nil)
3
+ # capture the sort column and whether sorting should be reversed (descending)
4
+ key, inline_desc = order.sub(/( desc)$/i,''), !!$1
5
+ desc = inline_desc if desc.nil?
6
+ last_class = self
7
+ joins = []
8
+ conditions = []
9
+ sum_column = nil
10
+
11
+ while matches = key.match(/^(?<first>[^\.]*)\.(?<rest>.*)$/)
12
+ first = matches[:first]
13
+ rest = matches[:rest]
14
+
15
+ if first.match(/^(.*)=(.*)$/)
16
+ conditions << last_class.arel_table[$1].eq($2)
17
+ elsif association = last_class.reflect_on_association(first.to_sym)
18
+ joins << first
19
+ last_class = association.klass
20
+ elsif rest == 'sum'
21
+ sum_column=first
22
+ end
23
+ key = rest
24
+ end
25
+
26
+ scope = scoped
27
+ if association = last_class.reflect_on_association(key.to_sym)
28
+ joins << key
29
+ last_class = association.klass
30
+ key = last_class.default_order_column
31
+ end
32
+
33
+ unless joins.empty?
34
+ join = Squeel::Nodes::Join.new(joins.shift.to_sym).outer
35
+ while nextjoin = joins.shift
36
+ join = join.send(nextjoin.to_sym).outer
37
+ end
38
+ scope = scope.joins join
39
+ end
40
+
41
+ conditions.each do |condition|
42
+ scope = scope.where condition
43
+ end
44
+
45
+ order =
46
+ if key == 'sum' or key == 'count'
47
+ group_bys = column_names.map{|c| "#{table_name}.#{c}"}
48
+ scope = scope.group(group_bys)
49
+ if key == 'count'
50
+ "COUNT(#{last_class.table_name}.id)"
51
+ else
52
+ "SUM(#{last_class.table_name}.#{sum_column})"
53
+ end
54
+ elsif last_class.respond_to?(special_method= "order_by_#{key}")
55
+ last_class.send special_method
56
+ else
57
+ "#{last_class.table_name}.#{key}"
58
+ end
59
+
60
+ order += " DESC" if desc
61
+ scope.order(order)
62
+ end
63
+
64
+
65
+ private
66
+
67
+ def self.default_order_column
68
+ 'name'
69
+ end
70
+
71
+ end
@@ -0,0 +1,5 @@
1
+ SmartOrder
2
+ ==========
3
+
4
+ SmartOrder::Sortable defines two methods, `smart_order` and
5
+ `default_order_column` which are used to sort the ActiveRecord::Relations smartly.
@@ -0,0 +1,68 @@
1
+ class SmartOrder::Sortable
2
+ def smart_order(key, desc)
3
+ last_class = self
4
+ joins = []
5
+ conditions = []
6
+ sum_column = nil
7
+
8
+ while matches = key.match(/^(?<first>[^\.]*)\.(?<rest>.*)$/)
9
+ first = matches[:first]
10
+ rest = matches[:rest]
11
+
12
+ if first.match(/^(.*)=(.*)$/)
13
+ conditions << last_class.arel_table[$1].eq($2)
14
+ elsif association = last_class.reflect_on_association(first.to_sym)
15
+ joins << first
16
+ last_class = association.klass
17
+ elsif rest == 'sum'
18
+ sum_column = first
19
+ end
20
+ key = rest
21
+ end
22
+
23
+ scope = scoped
24
+ if association = last_class.reflect_on_association(key.to_sym)
25
+ joins << key
26
+ last_class = association.klass
27
+ key = last_class.default_order_column
28
+ end
29
+
30
+ unless joins.empty?
31
+ join = Squeel::Nodes::Join.new(joins.shift.to_sym).outer
32
+ while nextjoin = joins.shift
33
+ join = join.send(nextjoin.to_sym).outer
34
+ end
35
+ scope = scope.joins join
36
+ end
37
+
38
+ conditions.each do |condition|
39
+ scope = scope.where condition
40
+ end
41
+
42
+ order =
43
+ if key == 'sum' or key == 'count'
44
+ group_bys = column_names.map{|c| "#{table_name}.#{c}"}
45
+ scope = scope.group(group_bys)
46
+ if key == 'count'
47
+ "COUNT(#{last_class.table_name}.id)"
48
+ else
49
+ "SUM(#{last_class.table_name}.#{sum_column})"
50
+ end
51
+ elsif last_class.respond_to?(special_method = "order_by_#{key}")
52
+ last_class.send special_method
53
+ else
54
+ "#{last_class.table_name}.#{key}"
55
+ end
56
+
57
+ order += " DESC" if desc
58
+ scope.order(order)
59
+ end
60
+
61
+
62
+ #private
63
+
64
+ def default_order_column
65
+ columns.map(&:name).include?('name') ? 'name' : 'id'
66
+ end
67
+
68
+ end
metadata ADDED
@@ -0,0 +1,211 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fancy_table
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Caleb Thompson
8
+ - Ram Dobson
9
+ - Sol Systems
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2014-02-05 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: coffee-filter
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: haml
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: kaminari
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ - !ruby/object:Gem::Dependency
58
+ name: rails
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ type: :runtime
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ - !ruby/object:Gem::Dependency
72
+ name: sass-rails
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ - !ruby/object:Gem::Dependency
86
+ name: squeel
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ type: :runtime
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ - !ruby/object:Gem::Dependency
100
+ name: cucumber-rails
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ type: :development
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ - !ruby/object:Gem::Dependency
114
+ name: database_cleaner
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ - !ruby/object:Gem::Dependency
128
+ name: factory_girl_rails
129
+ requirement: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ - !ruby/object:Gem::Dependency
142
+ name: rspec-rails
143
+ requirement: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ type: :development
149
+ prerelease: false
150
+ version_requirements: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ - !ruby/object:Gem::Dependency
156
+ name: sqlite3
157
+ requirement: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ type: :development
163
+ prerelease: false
164
+ version_requirements: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ description: |
170
+ Create fancy tables which are semantic HTML5, are easy tostyle, and are beautiful.
171
+ email:
172
+ - cjaysson@gmail.com
173
+ - fringd@gmail.com
174
+ - gems@solsystemscompany.com
175
+ executables: []
176
+ extensions: []
177
+ extra_rdoc_files: []
178
+ files:
179
+ - lib/fancy_table.rb
180
+ - lib/fancy_table/controller_methods.rb
181
+ - lib/fancy_table/railtie.rb
182
+ - lib/fancy_table/version.rb
183
+ - lib/fancy_table/view_helpers.rb
184
+ - lib/map_hash.rb
185
+ - lib/smart_order.rb
186
+ - lib/smart_order/README.md
187
+ - lib/smart_order/sortable.rb
188
+ homepage:
189
+ licenses: []
190
+ metadata: {}
191
+ post_install_message:
192
+ rdoc_options: []
193
+ require_paths:
194
+ - lib
195
+ required_ruby_version: !ruby/object:Gem::Requirement
196
+ requirements:
197
+ - - ">="
198
+ - !ruby/object:Gem::Version
199
+ version: '0'
200
+ required_rubygems_version: !ruby/object:Gem::Requirement
201
+ requirements:
202
+ - - ">="
203
+ - !ruby/object:Gem::Version
204
+ version: '0'
205
+ requirements: []
206
+ rubyforge_project: fancy_table
207
+ rubygems_version: 2.2.1
208
+ signing_key:
209
+ specification_version: 4
210
+ summary: Tables. Done right.
211
+ test_files: []