sorted 0.3.7 → 0.3.8

Sign up to get free protection for your applications and to get access to all the features.
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
-