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 CHANGED
@@ -17,5 +17,7 @@ tmtags
17
17
  coverage
18
18
  rdoc
19
19
  pkg
20
+ .rvmrc
21
+ Gemfile.lock
20
22
 
21
23
  ## PROJECT::SPECIFIC
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
- order(::Sorted::Sorter.new(params[:order], :sort => params[:sort]).to_sql)
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._:]+)\s([asc|ASC|desc|DESC]+)|[a-zA-Z._:]+)/)
39
- [(m[2].nil? ? m[1] : m[2]),(m[3].nil? ? "asc" : m[3].downcase)]
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{|a| "#{a[0]} #{a[1].upcase}"}.join(', ')
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
@@ -1,3 +1,3 @@
1
1
  module Example
2
- VERSION = "0.3.7"
2
+ VERSION = "0.3.8"
3
3
  end
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
- prerelease: false
5
- segments:
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
- date: 2010-12-16 00:00:00 +11:00
18
- default_executable:
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
- prerelease: false
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
- requirement: &id002 !ruby/object:Gem::Requirement
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
- requirement: &id003 !ruby/object:Gem::Requirement
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
- version_requirements: *id003
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
- segments:
81
+ requirements:
82
+ - - ! '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ segments:
108
86
  - 0
109
- version: "0"
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.3.7
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
-