simple-search 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.0
1
+ 0.10.0
@@ -21,12 +21,11 @@ module SimpleSearch
21
21
  def simplesearch(params={})
22
22
 
23
23
  arel = self.scoped unless self.is_a?(::ActiveRecord::Relation)
24
- params, where_params=filtered_params(params) # validate params
24
+ other_params, where_params=filtered_params(params) # validate params
25
25
  arel = with_ss_where(arel,where_params)
26
- arel = with_ss_group(arel,params['group_by'])
27
- arel = with_ss_order(arel,params['order_by'])
28
- #arel = with_ss_limit(arel,params)
29
- #arel = with_ss_order(arel,params)
26
+ arel = with_ss_group(arel,other_params['group_by'])
27
+ arel = with_ss_order(arel,other_params['order_by'])
28
+ arel = with_ss_limit_offset(arel,other_params)
30
29
  arel
31
30
  end
32
31
 
@@ -36,7 +35,7 @@ module SimpleSearch
36
35
  where_params = {}
37
36
  other_params = {}
38
37
  params.each do |key,value|
39
- if ["group_by","page_by","page_no","order_by"].include?(key)
38
+ if ["group_by","page_by","page", "order_by"].include?(key)
40
39
  other_params[key]=value
41
40
  else
42
41
  matches = /(.*)_([a-z]+)$/.match(key)
@@ -95,8 +94,11 @@ module SimpleSearch
95
94
  arel
96
95
  end
97
96
 
98
- def with_ss_limit(arel,params={})
99
- # TODO
97
+ def with_ss_limit_offset(arel,params)
98
+ page_num = (params['page'] || 1).to_i
99
+ page_by = (params['page_by'] || 50).to_i
100
+ arel = arel.limit(page_by).offset( (page_num-1)*page_by )
101
+ arel
100
102
  end
101
103
 
102
104
  end # end class methods
@@ -0,0 +1,3 @@
1
+ module SimpleSearch
2
+ class Exception < Exception; end
3
+ end
@@ -0,0 +1,123 @@
1
+ module SimpleSearch
2
+ module ViewHelper
3
+
4
+ # Example:
5
+ #
6
+ # <%= order_by :name %>
7
+ # <%= order_by :name, 'Company Name' %>
8
+ # <%= order_by :name, 'Company Name', :class=>'bold' %>
9
+ def order_link(attr, name=nil, html_options={})
10
+ raise Exception, "must be used in a view" unless (request.fullpath && request.parameters)
11
+
12
+ # check if order_by is in an url array
13
+ matches = request.fullpath.match Regexp.new("[\&\?]([a-z_]+)\\[order_by\\]=") # &array[order_by]
14
+ order_arr_key = (matches && matches.length == 2) ? matches[1] : nil
15
+
16
+ # get order_by value
17
+ order_by_value = order_arr_key ? request.parameters[order_arr_key][:order_by] : request.parameters[:order_by]
18
+ if order_by_value
19
+ order_by_col, current_order = order_by_value.split(" ")
20
+ else
21
+ order_by_col, current_order = attr, nil
22
+ end
23
+
24
+ # determine next order
25
+ next_order = {nil=>'asc', 'asc'=>'desc', 'desc'=>'asc'}[current_order]
26
+
27
+ # build new url params
28
+ new_url_params = if order_arr_key
29
+ old_arr = request.parameters[order_arr_key]
30
+ new_arr = old_arr.merge(:order_by => "#{order_by_col} #{next_order}")
31
+ request.parameters.merge(order_arr_key => new_arr)
32
+ else
33
+ request.parameters.merge(:order_by => "#{order_by_col} #{next_order}" )
34
+ end
35
+
36
+ # build link text
37
+ name ||= attr.to_s.humanize.titleize.strip
38
+ order_indicator = {nil=>'', 'asc'=>'&#9650;', 'desc'=>'&#9660;'}[current_order]
39
+ link_text = "#{name} #{order_indicator}".strip
40
+
41
+ link_to link_text, new_url_params, html_options
42
+ end
43
+
44
+ #
45
+ # Returns page related properties in hash
46
+ #
47
+ def page_properties(arel)
48
+ total_rows = arel.limit(1000000).offset(0).count
49
+
50
+ # check if page is in an url array
51
+ matches = request.fullpath.match Regexp.new("\&([a-z_]+)\\[page|page_by\\]=") # &array[page]
52
+ page_arr_key = (matches && matches.length == 2) ? matches[1] : nil
53
+
54
+ # get current page value
55
+ page = page_arr_key ? request.parameters[page_arr_key][:page] : request.parameters[:page]
56
+ page ||= 1
57
+ page = page.to_i
58
+
59
+ page_by = page_arr_key ? request.parameters[page_arr_key][:page_by] : request.parameters[:page_by]
60
+ page_by ||= 30
61
+ page_by = page_by.to_i
62
+
63
+ last_page = total_rows / page_by.to_i
64
+ last_page += 1 if total_rows % page_by.to_i != 0
65
+ {
66
+ :total_rows => total_rows,
67
+ :last_page => last_page,
68
+ :current_page => (page || 1).to_i,
69
+ :rows_per_page => (page_by || 30).to_i,
70
+ :page_arr_key => page_arr_key
71
+ }
72
+ end
73
+
74
+ #
75
+ # Returns a url params in hash for the page number given
76
+ #
77
+ def page_params(page_num, page_arr_key=nil)
78
+ params = if page_arr_key
79
+ old_arr = request.parameters[page_arr_key].with_indifferent_access
80
+ request.parameters.merge(page_arr_key => old_arr.merge(:page => page_num) )
81
+ else
82
+ request.parameters.merge(:page => page_num )
83
+ end
84
+ params.with_indifferent_access
85
+ end
86
+
87
+ #
88
+ # Returns page url params in hash with the page number as key
89
+ #
90
+ def page_url_params(arel, num_pages=5)
91
+ page_props = page_properties(arel)
92
+ num_bf_af = (num_pages-1)/2
93
+ current_page = page_props[:current_page]
94
+ last_page = page_props[:last_page]
95
+
96
+ page_numbers = [1, last_page]
97
+ page_numbers << ([current_page-num_bf_af,1].max..[current_page+num_bf_af,last_page].min).to_a
98
+ page_numbers << last_page
99
+ page_numbers = page_numbers.flatten.uniq.sort
100
+
101
+ page_url_params = {}
102
+ for num in page_numbers
103
+ page_url_params[num] = page_params(num, page_props[:page_arr_key])
104
+ end
105
+
106
+ page_url_params
107
+ end
108
+
109
+ def page_urls(arel, http_options={})
110
+ page_urls = []
111
+ prev_page = 0
112
+ page_url_params(arel).each { |page, url_params|
113
+ if page.to_i > (prev_page+1) # page number jumped up, need to have some indicator
114
+ page_urls << "<span class='filler'>...</span>"
115
+ end
116
+ page_urls << link_to(page, url_params, http_options)
117
+ prev_page = page
118
+ }
119
+ page_urls
120
+ end
121
+
122
+ end
123
+ end
data/lib/simple_search.rb CHANGED
@@ -3,6 +3,8 @@ require 'active_support'
3
3
  require 'action_view'
4
4
  require 'action_controller'
5
5
  require 'simple_search/active_record'
6
+ require 'simple_search/view_helper'
6
7
 
7
8
  ActiveRecord::Base.send(:include, SimpleSearch::ActiveRecord)
8
- #ActionController::Base.helper(MetaSearch::Helpers::UrlHelper)
9
+ ActionController::Base.helper(SimpleSearch::ViewHelper)
10
+
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "simple-search"
8
- s.version = "0.9.0"
8
+ s.version = "0.10.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Allen Kim"]
12
- s.date = "2012-03-10"
12
+ s.date = "2012-03-14"
13
13
  s.description = "\n\t\tTranslates url commands for searching, paging, sorting, groupion against ActiveRecord and its associations.\n\t\tProvides view helpers including links for order and urls for search, group, and page.\n\t"
14
14
  s.email = "bighostkim@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -25,10 +25,13 @@ Gem::Specification.new do |s|
25
25
  "VERSION",
26
26
  "lib/simple_search.rb",
27
27
  "lib/simple_search/active_record.rb",
28
+ "lib/simple_search/exception.rb",
29
+ "lib/simple_search/view_helper.rb",
28
30
  "simple-search.gemspec",
29
31
  "test/helper.rb",
30
32
  "test/tables_models.rb",
31
- "test/test_simple_search.rb"
33
+ "test/test_active_record.rb",
34
+ "test/test_view_helper.rb"
32
35
  ]
33
36
  s.homepage = "http://github.com/bighostkim/simple-search"
34
37
  s.licenses = ["MIT"]
@@ -10,6 +10,7 @@ ActiveRecord::Base.establish_connection(
10
10
  # drop tables
11
11
  ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'posts'")
12
12
  ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'comments'")
13
+ ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'post_likes'")
13
14
 
14
15
  # create tables
15
16
  ActiveRecord::Base.connection.create_table(:posts) do |t|
@@ -21,6 +22,23 @@ ActiveRecord::Base.connection.create_table(:comments) do |t|
21
22
  t.text :body
22
23
  t.boolean :spam_flag
23
24
  end
25
+ ActiveRecord::Base.connection.create_table(:post_likes) do |t|
26
+ t.string :post_id
27
+ t.boolean :like
28
+ end
29
+
30
+ # models
31
+ class Post < ActiveRecord::Base
32
+ has_many :comments
33
+ has_many :post_likes
34
+ end
35
+ class Comment < ActiveRecord::Base
36
+ belongs_to :post
37
+ has_many :votes
38
+ end
39
+ class PostLike < ActiveRecord::Base
40
+ belongs_to :post
41
+ end
24
42
 
25
43
  # insert tables
26
44
  ActiveRecord::Base.connection.execute("INSERT INTO posts (id,subject,body) VALUES (1, 'subject foo','body foo') ")
@@ -33,10 +51,10 @@ ActiveRecord::Base.connection.execute("INSERT INTO comments (id,post_id,body) VA
33
51
  ActiveRecord::Base.connection.execute("INSERT INTO comments (id,post_id,body,spam_flag) VALUES (31, 3,'post3 comment foo', 1) ")
34
52
  ActiveRecord::Base.connection.execute("INSERT INTO comments (id,post_id,body,spam_flag) VALUES (32, 3,'post3 comment bar', 0) ")
35
53
 
36
- # models
37
- class Post < ActiveRecord::Base
38
- has_many :comments
39
- end
40
- class Comment < ActiveRecord::Base
41
- belongs_to :post
54
+ Post.all.each do |post|
55
+ for n in 1..100
56
+ post_like = PostLike.new(:post => post, :like=> rand(2))
57
+ post_like.save
58
+ end
42
59
  end
60
+
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
 
3
- class TestSimpleSearch < Test::Unit::TestCase
3
+ class TestActiveRecord < Test::Unit::TestCase
4
4
 
5
5
  should "work with arel where conditions" do
6
6
  posts_comments = Post.select('posts.*, comments.body as comment').joins(:comments)
@@ -57,8 +57,19 @@ class TestSimpleSearch < Test::Unit::TestCase
57
57
  assert_equal 32, result.first.comment_id
58
58
  end
59
59
 
60
- should "work with arel limit conditions" do
61
- true
60
+ should "work with arel limit and offset conditions" do
61
+ posts_comments = Post.select('posts.*, comments.id as comment_id, comments.body as comment').joins(:comments)
62
+ result = posts_comments.simplesearch('order_by'=>'comment_id', 'page_by'=>2)
63
+ assert_equal [11,12], result.map {|r| r.comment_id}
64
+
65
+ result = posts_comments.simplesearch('order_by'=>'comment_id', 'page'=> 1, 'page_by'=>2)
66
+ assert_equal [11,12], result.map {|r| r.comment_id}
67
+
68
+ result = posts_comments.simplesearch('order_by'=>'comment_id', 'page'=> 2, 'page_by'=>2)
69
+ assert_equal [21,22], result.map {|r| r.comment_id}
70
+
71
+ result = posts_comments.simplesearch('order_by'=>'comment_id', 'page'=> 3, 'page_by'=>2)
72
+ assert_equal [31,32], result.map {|r| r.comment_id}
62
73
  end
63
74
 
64
75
  end
@@ -0,0 +1,97 @@
1
+ require 'helper'
2
+ require 'action_view/test_case'
3
+
4
+ class TestViewHelper < Test::Unit::TestCase
5
+ class MyView < ActionView::Base
6
+ include SimpleSearch::ViewHelper
7
+ end
8
+
9
+ def setup
10
+ @view = MyView.new
11
+ router = ActionDispatch::Routing::RouteSet.new
12
+ router.draw do
13
+ match ':controller(/:action(/:id(.:format)))'
14
+ end
15
+ @view.instance_variable_set(:@_routes, router)
16
+ end
17
+
18
+ should "generate order by link" do
19
+ @view.request = ActionController::TestRequest.new({"SCRIPT_NAME"=>"/tests",
20
+ "QUERY_STRING"=>"controller=tests&a=1&b=2"})
21
+ assert_match "order_by=foo+asc", @view.order_link(:foo)
22
+ assert_match ">Foo Bar<", @view.order_link(:foo_bar)
23
+ assert_match ">Custom Name<", @view.order_link(:foo, "Custom Name")
24
+ assert_match "class=\"bar\"", @view.order_link(:foo, "Name", :class=>:bar)
25
+
26
+ @view.request = ActionController::TestRequest.new({"SCRIPT_NAME"=>"/tests",
27
+ "QUERY_STRING"=>"controller=tests&order_by=foo+asc&a=1&b=2"})
28
+ assert_match "order_by=foo+desc", @view.order_link(:foo)
29
+ assert_match ">Foo &amp;#9650;<", @view.order_link(:foo)
30
+
31
+ @view.request = ActionController::TestRequest.new({"SCRIPT_NAME"=>"/tests",
32
+ "QUERY_STRING"=>"controller=tests&order_by=foo+desc&a=1&b=2"})
33
+ assert_match "order_by=foo+asc", @view.order_link(:foo)
34
+ assert_match ">Foo &amp;#9660;<", @view.order_link(:foo)
35
+
36
+ @view.request = ActionController::TestRequest.new({"SCRIPT_NAME"=>"/tests",
37
+ "QUERY_STRING"=>"controller=tests&ss[order_by]=foo+desc&a=1&b=2"})
38
+ assert_match "ss%5Border_by%5D=foo+asc", @view.order_link(:foo)
39
+ assert_match ">Foo &amp;#9660;<", @view.order_link(:foo)
40
+ end
41
+
42
+ should "generate page properties" do
43
+ @view.request = ActionController::TestRequest.new({"SCRIPT_NAME"=>"/tests",
44
+ "QUERY_STRING"=>"controller=tests&page_by=2"})
45
+ arel = Post.select('posts.*, comments.*').joins(:comments).simplesearch(:page_by=>2)
46
+
47
+ @view.page_properties(arel)
48
+ assert_equal ({ :total_rows => 6, :last_page => 3, :current_page => 1,
49
+ :rows_per_page => 2, :page_arr_key => nil }), @view.page_properties(arel)
50
+
51
+ @view.request = ActionController::TestRequest.new({"SCRIPT_NAME"=>"/tests",
52
+ "QUERY_STRING"=>"controller=tests&ss[page_by]=2"})
53
+ assert_equal ({ :total_rows => 6, :last_page => 3, :current_page => 1,
54
+ :rows_per_page => 2, :page_arr_key => "ss" }), @view.page_properties(arel)
55
+ end
56
+
57
+ should "generate url params for single page" do
58
+ @view.request = ActionController::TestRequest.new({"SCRIPT_NAME"=>"/tests",
59
+ "QUERY_STRING"=>"controller=tests&page_by=2"})
60
+ params = @view.page_params(3)
61
+ assert_equal 2, params[:page_by].to_i
62
+ assert_equal 3, params[:page]
63
+
64
+ @view.request = ActionController::TestRequest.new({"SCRIPT_NAME"=>"/tests",
65
+ "QUERY_STRING"=>"controller=tests&ss[page_by]=2"})
66
+ params = @view.page_params(3, "ss")
67
+ assert_equal 2, params[:ss][:page_by].to_i
68
+ assert_equal 3, params[:ss][:page]
69
+ end
70
+
71
+ should "generate url params for many pages" do
72
+ arel = Post.select('posts.*, post_likes.*').joins(:post_likes).simplesearch(:page_by=>30)
73
+ @view.request = ActionController::TestRequest.new({"SCRIPT_NAME"=>"/tests",
74
+ "QUERY_STRING"=>"controller=tests&page=5&page_by=10"})
75
+ url_params = @view.page_url_params(arel)
76
+ assert_equal [1,3,4,5,6,7,30], url_params.keys
77
+ assert_equal 10, url_params[5][:page_by].to_i
78
+ assert_equal 5, url_params[5][:page].to_i
79
+
80
+ @view.request = ActionController::TestRequest.new({"SCRIPT_NAME"=>"/tests",
81
+ "QUERY_STRING"=>"controller=tests&ss[page_by]=2"})
82
+ url_params = @view.page_url_params(arel)
83
+ assert_equal 2, url_params[1][:ss][:page_by].to_i
84
+ assert_equal 1, url_params[1][:ss][:page].to_i
85
+ end
86
+
87
+ should "generate page urls" do
88
+ arel = Post.select('posts.*, post_likes.*').joins(:post_likes).simplesearch(:page_by=>30)
89
+ @view.request = ActionController::TestRequest.new({"SCRIPT_NAME"=>"/tests",
90
+ "QUERY_STRING"=>"controller=tests&page=5&page_by=10"})
91
+ page_urls = @view.page_urls(arel)
92
+ assert_equal 9, page_urls.length # 1 ... 3 4 5 6 7 ... 10
93
+ assert_equal "<span class='filler'>...</span>", page_urls[1]
94
+ assert_equal "<span class='filler'>...</span>", page_urls[7]
95
+ end
96
+
97
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: simple-search
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.9.0
5
+ version: 0.10.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Allen Kim
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-03-10 00:00:00 Z
13
+ date: 2012-03-14 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -132,10 +132,13 @@ files:
132
132
  - VERSION
133
133
  - lib/simple_search.rb
134
134
  - lib/simple_search/active_record.rb
135
+ - lib/simple_search/exception.rb
136
+ - lib/simple_search/view_helper.rb
135
137
  - simple-search.gemspec
136
138
  - test/helper.rb
137
139
  - test/tables_models.rb
138
- - test/test_simple_search.rb
140
+ - test/test_active_record.rb
141
+ - test/test_view_helper.rb
139
142
  homepage: http://github.com/bighostkim/simple-search
140
143
  licenses:
141
144
  - MIT
@@ -149,7 +152,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
149
152
  requirements:
150
153
  - - ">="
151
154
  - !ruby/object:Gem::Version
152
- hash: 2459026480116491864
155
+ hash: -3264573546871737364
153
156
  segments:
154
157
  - 0
155
158
  version: "0"