simple-search 0.9.0 → 0.10.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.
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"