sorted 0.3.7 → 0.3.8
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/.gitignore +2 -0
- data/.watchr +24 -0
- data/README.rdoc +7 -1
- data/lib/sorted/finders/active_record.rb +26 -1
- data/lib/sorted/sorter.rb +21 -3
- data/lib/sorted/version.rb +1 -1
- data/spec/sorted_spec.rb +31 -0
- data/spec/sorter_spec.rb +10 -3
- metadata +44 -72
data/.gitignore
CHANGED
data/.watchr
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module WatchrActions
|
2
|
+
def self.run_spec(file)
|
3
|
+
unless File.exist?(file)
|
4
|
+
puts "#{file} does not exist"
|
5
|
+
return
|
6
|
+
end
|
7
|
+
|
8
|
+
puts "Running #{file}"
|
9
|
+
system "rspec #{file}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
watch(/^lib\/(?:sorted\/)?(.*).rb/) do |m|
|
14
|
+
WatchrActions.run_spec("spec/#{m[1]}_spec.rb")
|
15
|
+
end
|
16
|
+
|
17
|
+
watch(/^spec\/.*_spec.rb/) do |m|
|
18
|
+
WatchrActions.run_spec(m[0])
|
19
|
+
end
|
20
|
+
|
21
|
+
watch(/^lib\/sorted\/finders\/active_record.rb/) do |m|
|
22
|
+
WatchrActions.run_spec('spec/sorted_spec.rb')
|
23
|
+
end
|
24
|
+
|
data/README.rdoc
CHANGED
@@ -28,7 +28,13 @@ This will initially sort by email ascending:
|
|
28
28
|
|
29
29
|
@users = User.sorted(:order => "email ASC", :sort => params[:sort]).paginate(:page => params[:page])
|
30
30
|
|
31
|
-
Or you can just clone the example app https://github.com/mynameisrufus/sorted_app
|
31
|
+
Or you can just clone the example app https://github.com/mynameisrufus/sorted_app.
|
32
|
+
|
33
|
+
If you want to sort by a belongs_to relationship, just provide sort order as "RELATIONS.COLUMN ASC|DESC" where
|
34
|
+
RELATIONS is the name of the relationship table and COLUMN is an attribute in that table. For example,
|
35
|
+
assuming the User model belongs_to a :company.
|
36
|
+
|
37
|
+
@users = User.sorted(:order => "companies.name asc", :sort => params[:sort]).paginate(:page => params[:page])
|
32
38
|
|
33
39
|
== Presentation
|
34
40
|
|
@@ -6,8 +6,33 @@ module Sorted
|
|
6
6
|
module ActiveRecord
|
7
7
|
def self.enable!
|
8
8
|
::ActiveRecord::Base.class_eval do
|
9
|
+
# Define a symbolic sort column. This allows mapping a simple column name
|
10
|
+
# to a more complex sql order clause.
|
11
|
+
# class Model < ActiveRecord::Base
|
12
|
+
# symbolic_sort :ip_address, 'inet_aton(`ip_address`)'
|
13
|
+
# end
|
14
|
+
def self.symbolic_sort(key, sql)
|
15
|
+
symbolic_sorts[key] = sql
|
16
|
+
end
|
17
|
+
|
9
18
|
def self.sorted(params)
|
10
|
-
|
19
|
+
sorter = ::Sorted::Sorter.new(params[:order], :sort => params[:sort], :symbolic_sorts => symbolic_sorts)
|
20
|
+
# Check if we parsed some relationship includes and apply them
|
21
|
+
# before applying the order
|
22
|
+
relation = self
|
23
|
+
if sorter.includes.size > 0
|
24
|
+
# Remove self.name from includes
|
25
|
+
my_name = self.name.to_sym
|
26
|
+
real_includes = sorter.includes.delete_if{|include_name| include_name == my_name}
|
27
|
+
relation = includes(real_includes) if real_includes.size > 0
|
28
|
+
end
|
29
|
+
relation.order(sorter.to_sql)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def self.symbolic_sorts
|
35
|
+
@symbolic_sorts ||= {}
|
11
36
|
end
|
12
37
|
end
|
13
38
|
end
|
data/lib/sorted/sorter.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
module Sorted
|
2
2
|
class Sorter
|
3
|
+
attr_reader :includes
|
3
4
|
def initialize(order, params = nil)
|
5
|
+
@includes = []
|
6
|
+
@symbolic_sorts = {}
|
7
|
+
|
4
8
|
if order.is_a?(String) || order.is_a?(Symbol)
|
5
9
|
parse_order(order)
|
6
10
|
end
|
@@ -9,6 +13,7 @@ module Sorted
|
|
9
13
|
if @params[:sort].is_a?(String)
|
10
14
|
parse_sort @params[:sort]
|
11
15
|
end
|
16
|
+
@symbolic_sorts = @params[:symbolic_sorts] || {}
|
12
17
|
end
|
13
18
|
end
|
14
19
|
|
@@ -30,13 +35,23 @@ module Sorted
|
|
30
35
|
|
31
36
|
def parse_query(sort)
|
32
37
|
if m = sort.match(/([a-zA-Z0-9._]+)_(asc|desc)$/)
|
38
|
+
parse_include(m[1])
|
33
39
|
[m[1],m[2]]
|
34
40
|
end
|
35
41
|
end
|
36
42
|
|
37
43
|
def parse_sql(order)
|
38
|
-
if m = order.match(/(([a-zA-Z._:]
|
39
|
-
|
44
|
+
if m = order.match(/(([a-zA-Z._:][a-zA-Z._:0-9]*)\s([asc|ASC|desc|DESC]+)|[a-zA-Z._:][a-zA-Z._:0-9]*)/)
|
45
|
+
sort_column = (m[2].nil? ? m[1] : m[2])
|
46
|
+
parse_include(sort_column)
|
47
|
+
[sort_column,(m[3].nil? ? "asc" : m[3].downcase)]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def parse_include(order)
|
52
|
+
if match_data = /^([^\.]+)\..+/.match(order)
|
53
|
+
include_name = match_data[1].singularize.to_sym
|
54
|
+
@includes << include_name unless @includes.include?(include_name)
|
40
55
|
end
|
41
56
|
end
|
42
57
|
|
@@ -55,7 +70,10 @@ module Sorted
|
|
55
70
|
end
|
56
71
|
|
57
72
|
def to_sql
|
58
|
-
array.map
|
73
|
+
array.map do |a|
|
74
|
+
column = @symbolic_sorts[a[0].to_sym] || a[0]
|
75
|
+
"#{column} #{a[1].upcase}"
|
76
|
+
end.join(', ')
|
59
77
|
end
|
60
78
|
|
61
79
|
def to_s
|
data/lib/sorted/version.rb
CHANGED
data/spec/sorted_spec.rb
CHANGED
@@ -10,6 +10,34 @@ describe Sorted::Finders::ActiveRecord do
|
|
10
10
|
it "should integrate with ActiveRecord::Base" do
|
11
11
|
ActiveRecord::Base.should respond_to(:sorted)
|
12
12
|
end
|
13
|
+
|
14
|
+
it "should define a symbolic_sorts method" do
|
15
|
+
ActiveRecord::Base.should respond_to(:symbolic_sort)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should define symbolic_sorts" do
|
19
|
+
a = Class.new(ActiveRecord::Base)
|
20
|
+
b = Class.new(ActiveRecord::Base)
|
21
|
+
|
22
|
+
a.symbolic_sort(:foo, 'foo')
|
23
|
+
b.symbolic_sort(:bar, 'bar')
|
24
|
+
|
25
|
+
a.instance_variable_get(:@symbolic_sorts).should == {:foo => 'foo'}
|
26
|
+
b.instance_variable_get(:@symbolic_sorts).should == {:bar => 'bar'}
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should add orders to the relation" do
|
30
|
+
a = Class.new(ActiveRecord::Base)
|
31
|
+
relation = a.sorted(:order => nil, :sort => 'a_asc')
|
32
|
+
relation.order_values.should == ["a ASC"]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should add orders to the relation using symbolic_sorts" do
|
36
|
+
a = Class.new(ActiveRecord::Base)
|
37
|
+
a.symbolic_sort(:ip, 'inet_aton(`ip`)')
|
38
|
+
relation = a.sorted(:order => nil, :sort => 'ip_asc')
|
39
|
+
relation.order_values.should == ["inet_aton(`ip`) ASC"]
|
40
|
+
end
|
13
41
|
end
|
14
42
|
|
15
43
|
describe Sorted::ViewHelpers::ActionView do
|
@@ -26,6 +54,9 @@ describe Sorted::ViewHelpers::ActionView do
|
|
26
54
|
def request
|
27
55
|
Request.new
|
28
56
|
end
|
57
|
+
|
58
|
+
def _prefixes
|
59
|
+
end
|
29
60
|
end
|
30
61
|
class Request
|
31
62
|
def get?; true end
|
data/spec/sorter_spec.rb
CHANGED
@@ -17,9 +17,10 @@ describe Sorted::Sorter, "parse methods" do
|
|
17
17
|
sorter.sorts.should == [["email", "desc"], ["name", "desc"]]
|
18
18
|
end
|
19
19
|
|
20
|
-
it "should allow underscores, full stops and colons in" do
|
21
|
-
sorter = Sorted::Sorter.new('users.email ASC, users.phone_number DESC, assessments.name ASC, assessments.number_as_string::BigInt', {:sort => "users.email_desc!users.first_name_desc"})
|
22
|
-
sorter.to_sql.should == "users.email DESC, users.first_name DESC, users.phone_number DESC, assessments.name ASC, assessments.number_as_string::BigInt ASC"
|
20
|
+
it "should allow numbers, underscores, full stops and colons in" do
|
21
|
+
sorter = Sorted::Sorter.new('users.email ASC, users.phone_number DESC, assessments.name ASC, assessments.number_as_string::BigInt, assessments.column_with_number_123', {:sort => "users.email_desc!users.first_name_desc"})
|
22
|
+
sorter.to_sql.should == "users.email DESC, users.first_name DESC, users.phone_number DESC, assessments.name ASC, assessments.number_as_string::BigInt ASC, assessments.column_with_number_123 ASC"
|
23
|
+
sorter.includes.size.should == 2
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
@@ -27,6 +28,7 @@ describe Sorted::Sorter, "logic:" do
|
|
27
28
|
it "should not toggle the sort order and include any sql orders not in sort params" do
|
28
29
|
sorter = Sorted::Sorter.new("email ASC, phone ASC, name DESC", {:sort => "email_desc!name_desc"})
|
29
30
|
sorter.to_a.should == [["email", "desc"], ["name", "desc"], ["phone", "asc"]]
|
31
|
+
sorter.includes.size.should == 0
|
30
32
|
end
|
31
33
|
|
32
34
|
it "should return an sql sort string" do
|
@@ -43,6 +45,11 @@ describe Sorted::Sorter, "logic:" do
|
|
43
45
|
sorter = Sorted::Sorter.new('email ASC, phone DESC, name ASC', {:sort => "email_desc!name_desc"})
|
44
46
|
sorter.to_sql.should == "email DESC, name DESC, phone DESC"
|
45
47
|
end
|
48
|
+
|
49
|
+
it "should substitute symbolic sorts" do
|
50
|
+
sorter = Sorted::Sorter.new('ip_address', :symbolic_sorts => {:ip_address => 'inet_aton(`ip_address`)'})
|
51
|
+
sorter.to_sql.should == "inet_aton(`ip_address`) ASC"
|
52
|
+
end
|
46
53
|
end
|
47
54
|
|
48
55
|
describe Sorted::Sorter, "to_css" do
|
metadata
CHANGED
@@ -1,79 +1,59 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: sorted
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 3
|
8
|
-
- 7
|
9
|
-
version: 0.3.7
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.8
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Rufus Post
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-10-04 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: bundler
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70138519878420 !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
26
|
-
- -
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
segments:
|
29
|
-
- 1
|
30
|
-
- 0
|
31
|
-
- 0
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
32
21
|
version: 1.0.0
|
33
22
|
type: :development
|
34
|
-
version_requirements: *id001
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: rails
|
37
23
|
prerelease: false
|
38
|
-
|
24
|
+
version_requirements: *70138519878420
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rails
|
27
|
+
requirement: &70138519876540 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
|
-
requirements:
|
41
|
-
- -
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
segments:
|
44
|
-
- 3
|
45
|
-
- 0
|
46
|
-
- 0
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
47
32
|
version: 3.0.0
|
48
33
|
type: :development
|
49
|
-
version_requirements: *id002
|
50
|
-
- !ruby/object:Gem::Dependency
|
51
|
-
name: rspec
|
52
34
|
prerelease: false
|
53
|
-
|
35
|
+
version_requirements: *70138519876540
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70138519874500 !ruby/object:Gem::Requirement
|
54
39
|
none: false
|
55
|
-
requirements:
|
56
|
-
- -
|
57
|
-
- !ruby/object:Gem::Version
|
58
|
-
segments:
|
59
|
-
- 2
|
60
|
-
- 0
|
61
|
-
- 0
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
62
43
|
version: 2.0.0
|
63
44
|
type: :development
|
64
|
-
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70138519874500
|
65
47
|
description: lets you sort large data sets using view helpers and a scope
|
66
|
-
email:
|
48
|
+
email:
|
67
49
|
- rufuspost@gmail.com
|
68
50
|
executables: []
|
69
|
-
|
70
51
|
extensions: []
|
71
|
-
|
72
52
|
extra_rdoc_files: []
|
73
|
-
|
74
|
-
files:
|
53
|
+
files:
|
75
54
|
- .document
|
76
55
|
- .gitignore
|
56
|
+
- .watchr
|
77
57
|
- Gemfile
|
78
58
|
- LICENSE
|
79
59
|
- README.rdoc
|
@@ -90,39 +70,31 @@ files:
|
|
90
70
|
- spec/sorter_spec.rb
|
91
71
|
- spec/spec_helper.rb
|
92
72
|
- spec/toggler_spec.rb
|
93
|
-
has_rdoc: true
|
94
73
|
homepage: http://rubygems.org/gems/sorted
|
95
74
|
licenses: []
|
96
|
-
|
97
75
|
post_install_message:
|
98
76
|
rdoc_options: []
|
99
|
-
|
100
|
-
require_paths:
|
77
|
+
require_paths:
|
101
78
|
- lib
|
102
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
80
|
none: false
|
104
|
-
requirements:
|
105
|
-
- -
|
106
|
-
- !ruby/object:Gem::Version
|
107
|
-
|
81
|
+
requirements:
|
82
|
+
- - ! '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
segments:
|
108
86
|
- 0
|
109
|
-
|
110
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
hash: 1254694282220959241
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
89
|
none: false
|
112
|
-
requirements:
|
113
|
-
- -
|
114
|
-
- !ruby/object:Gem::Version
|
115
|
-
segments:
|
116
|
-
- 1
|
117
|
-
- 3
|
118
|
-
- 6
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
119
93
|
version: 1.3.6
|
120
94
|
requirements: []
|
121
|
-
|
122
95
|
rubyforge_project: sorted
|
123
|
-
rubygems_version: 1.
|
96
|
+
rubygems_version: 1.8.10
|
124
97
|
signing_key:
|
125
98
|
specification_version: 3
|
126
99
|
summary: sort data with a database
|
127
100
|
test_files: []
|
128
|
-
|