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 +1 -1
- data/lib/simple_search/active_record.rb +10 -8
- data/lib/simple_search/exception.rb +3 -0
- data/lib/simple_search/view_helper.rb +123 -0
- data/lib/simple_search.rb +3 -1
- data/simple-search.gemspec +6 -3
- data/test/tables_models.rb +24 -6
- data/test/{test_simple_search.rb → test_active_record.rb} +14 -3
- data/test/test_view_helper.rb +97 -0
- metadata +7 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
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
|
-
|
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,
|
27
|
-
arel = with_ss_order(arel,
|
28
|
-
|
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","
|
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
|
99
|
-
|
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,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'=>'▲', 'desc'=>'▼'}[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
|
-
|
9
|
+
ActionController::Base.helper(SimpleSearch::ViewHelper)
|
10
|
+
|
data/simple-search.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "simple-search"
|
8
|
-
s.version = "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-
|
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/
|
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"]
|
data/test/tables_models.rb
CHANGED
@@ -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
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
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
|
-
|
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 &#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 &#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 &#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.
|
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-
|
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/
|
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:
|
155
|
+
hash: -3264573546871737364
|
153
156
|
segments:
|
154
157
|
- 0
|
155
158
|
version: "0"
|