tanker 1.1.2 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/VERSION +1 -1
- data/lib/tanker/pagination/kaminari.rb +38 -0
- data/lib/tanker/pagination/will_paginate.rb +15 -0
- data/lib/tanker/pagination.rb +16 -0
- data/lib/tanker.rb +12 -30
- data/spec/integration_spec.rb +206 -144
- data/spec/tanker_spec.rb +4 -4
- data/tanker.gemspec +5 -3
- metadata +5 -3
- data/lib/tanker/paginated_array.rb +0 -30
data/Gemfile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.1.
|
1
|
+
1.1.3
|
@@ -0,0 +1,38 @@
|
|
1
|
+
unless defined? Kaminari
|
2
|
+
raise(Tanker::BadConfiguration, "Tanker: Please add 'kaminari' to your Gemfile to use kaminari pagination backend")
|
3
|
+
end
|
4
|
+
|
5
|
+
module Tanker
|
6
|
+
module Pagination
|
7
|
+
class Kaminari < Array
|
8
|
+
include ::Kaminari::ConfigurationMethods::ClassMethods
|
9
|
+
include ::Kaminari::PageScopeMethods
|
10
|
+
|
11
|
+
attr_reader :limit_value, :offset_value, :total_count
|
12
|
+
|
13
|
+
def initialize(original_array, limit_val, offset_val, total_count)
|
14
|
+
@limit_value = limit_val || default_per_page
|
15
|
+
@offset_value, @total_count = offset_val, total_count
|
16
|
+
super(original_array)
|
17
|
+
end
|
18
|
+
|
19
|
+
def page(num = 1)
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def limit(num)
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def current_page
|
28
|
+
offset_value+1
|
29
|
+
end
|
30
|
+
|
31
|
+
class << self
|
32
|
+
def create(results, total_hits, options = {})
|
33
|
+
new(results, options[:per_page], options[:page]-1, total_hits)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
begin
|
2
|
+
require 'will_paginate/collection'
|
3
|
+
rescue LoadError
|
4
|
+
raise(Tanker::BadConfiguration, "Tanker: Please add 'will_paginate' to your Gemfile to use will_paginate pagination backend")
|
5
|
+
end
|
6
|
+
|
7
|
+
module Tanker
|
8
|
+
module Pagination
|
9
|
+
class WillPaginate
|
10
|
+
def self.create(results, total_hits, options = {})
|
11
|
+
::WillPaginate::Collection.create(options[:page], options[:per_page], total_hits) { |pager| pager.replace results }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Tanker
|
2
|
+
module Pagination
|
3
|
+
|
4
|
+
autoload :WillPaginate, 'tanker/pagination/will_paginate'
|
5
|
+
autoload :Kaminari, 'tanker/pagination/kaminari'
|
6
|
+
|
7
|
+
def self.create(results, total_hits, options = {})
|
8
|
+
begin
|
9
|
+
backend = Tanker.configuration[:pagination_backend].to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } # classify pagination backend name
|
10
|
+
Object.const_get(:Tanker).const_get(:Pagination).const_get(backend).create(results, total_hits, options)
|
11
|
+
rescue NameError
|
12
|
+
raise(BadConfiguration, "Unknown pagination backend")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/tanker.rb
CHANGED
@@ -9,7 +9,6 @@ end
|
|
9
9
|
require 'indextank_client'
|
10
10
|
require 'tanker/configuration'
|
11
11
|
require 'tanker/utilities'
|
12
|
-
require 'will_paginate/collection'
|
13
12
|
|
14
13
|
if defined? Rails
|
15
14
|
begin
|
@@ -28,7 +27,7 @@ module Tanker
|
|
28
27
|
autoload :Configuration, 'tanker/configuration'
|
29
28
|
extend Configuration
|
30
29
|
|
31
|
-
autoload :
|
30
|
+
autoload :Pagination, 'tanker/pagination'
|
32
31
|
|
33
32
|
class << self
|
34
33
|
attr_reader :included_in
|
@@ -101,26 +100,26 @@ module Tanker
|
|
101
100
|
|
102
101
|
# fetch values from index tank or just the type and id to instace results localy
|
103
102
|
options[:fetch] = "__type,__id"
|
104
|
-
options[:fetch] += ",#{fetch.join(',')}" if fetch
|
103
|
+
options[:fetch] += ",#{fetch.join(',')}" if fetch
|
105
104
|
options[:snippet] = snippets.join(',') if snippets
|
106
|
-
|
105
|
+
|
107
106
|
search_on_fields = models.map{|model| model.tanker_config.indexes.map{|arr| arr[0]}.uniq}.flatten.uniq.join(":(#{query.to_s}) OR ")
|
108
|
-
query = "#{search_on_fields}:(#{query.to_s}) __type:(#{models.map(&:name).map {|name| "\"#{name.split('::').join(' ')}\"" }.join(' OR ')})"
|
109
107
|
|
108
|
+
query = "#{search_on_fields}:(#{query.to_s}) OR __any:(#{query.to_s}) __type:(#{models.map(&:name).map {|name| "\"#{name.split('::').join(' ')}\"" }.join(' OR ')})"
|
110
109
|
options = { :start => paginate[:per_page] * (paginate[:page] - 1), :len => paginate[:per_page] }.merge(options) if paginate
|
111
110
|
results = index.search(query, options)
|
112
|
-
|
111
|
+
|
113
112
|
instantiated_results = if (fetch || snippets)
|
114
113
|
instantiate_results_from_results(results, fetch, snippets)
|
115
114
|
else
|
116
115
|
instantiate_results_from_db(results)
|
117
116
|
end
|
118
|
-
paginate === false ? instantiated_results :
|
117
|
+
paginate === false ? instantiated_results : Pagination.create(instantiated_results, results['matches'], paginate)
|
119
118
|
end
|
120
119
|
|
121
120
|
protected
|
122
121
|
|
123
|
-
def instantiate_results_from_db(index_result)
|
122
|
+
def instantiate_results_from_db(index_result)
|
124
123
|
results = index_result['results']
|
125
124
|
return [] if results.empty?
|
126
125
|
|
@@ -131,7 +130,7 @@ module Tanker
|
|
131
130
|
acc[model] << id
|
132
131
|
acc
|
133
132
|
end
|
134
|
-
|
133
|
+
|
135
134
|
id_map.each do |klass, ids|
|
136
135
|
# replace the id list with an eager-loaded list of records for this model
|
137
136
|
id_map[klass] = constantize(klass).find(ids)
|
@@ -143,26 +142,10 @@ module Tanker
|
|
143
142
|
end
|
144
143
|
end
|
145
144
|
|
146
|
-
def paginate_results(results, pagination_options, total_hits)
|
147
|
-
case Tanker.configuration[:pagination_backend]
|
148
|
-
when :will_paginate
|
149
|
-
WillPaginate::Collection.create(pagination_options[:page],
|
150
|
-
pagination_options[:per_page],
|
151
|
-
total_hits) { |pager| pager.replace results }
|
152
|
-
when :kaminari
|
153
|
-
Tanker::KaminariPaginatedArray.new(results,
|
154
|
-
pagination_options[:per_page],
|
155
|
-
pagination_options[:page]-1,
|
156
|
-
total_hits)
|
157
|
-
else
|
158
|
-
raise(BadConfiguration, "Unknown pagination backend")
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
145
|
def instantiate_results_from_results(index_result, fetch = false, snippets = false)
|
163
146
|
results = index_result['results']
|
164
147
|
return [] if results.empty?
|
165
|
-
instances = []
|
148
|
+
instances = []
|
166
149
|
id_map = results.inject({}) do |acc, result|
|
167
150
|
model = result["__type"]
|
168
151
|
instance = constantize(model).new()
|
@@ -366,10 +349,9 @@ module Tanker
|
|
366
349
|
|
367
350
|
#dynamically create a snippet read attribute (method)
|
368
351
|
def create_snippet_attribute(key, value)
|
369
|
-
#
|
370
|
-
|
371
|
-
|
372
|
-
end
|
352
|
+
# method name should something_snippet not snippet_something as the api returns it
|
353
|
+
method_name = "#{key.match(/snippet_(\w+)/)[1]}_snippet"
|
354
|
+
(class << self; self end).send(:define_method, method_name) { value }
|
373
355
|
end
|
374
356
|
|
375
357
|
def tanker_index_options
|
data/spec/integration_spec.rb
CHANGED
@@ -16,9 +16,10 @@ ActiveRecord::Base.establish_connection(
|
|
16
16
|
|
17
17
|
ActiveRecord::Schema.define do
|
18
18
|
create_table :products do |t|
|
19
|
-
t.string :name
|
19
|
+
t.string :name
|
20
20
|
t.string :href
|
21
21
|
t.string :tags
|
22
|
+
t.text :description
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
@@ -28,156 +29,217 @@ class Product < ActiveRecord::Base
|
|
28
29
|
tankit 'tanker_integration_tests' do
|
29
30
|
indexes :name
|
30
31
|
indexes :href
|
32
|
+
indexes :tags
|
33
|
+
indexes :description
|
31
34
|
end
|
32
35
|
end
|
33
36
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
# tankit 'tanker_integration_tests' do
|
38
|
-
# indexes :name
|
39
|
-
# indexes :href
|
40
|
-
# indexes :tags
|
41
|
-
# end
|
42
|
-
|
43
|
-
# attr_accessor :name, :href, :tags
|
44
|
-
|
45
|
-
# def initialize(options = {})
|
46
|
-
# @name = options[:name]
|
47
|
-
# @href = options[:href]
|
48
|
-
# @tags = options[:tags]
|
49
|
-
# end
|
50
|
-
|
51
|
-
# def id
|
52
|
-
# @id ||= self.class.throwaway_id
|
53
|
-
# end
|
54
|
-
#
|
55
|
-
# def id=(val)
|
56
|
-
# @id = val
|
57
|
-
# end
|
58
|
-
#
|
59
|
-
# class << self
|
60
|
-
# def create(options)
|
61
|
-
# self.new(options)
|
62
|
-
# end
|
63
|
-
#
|
64
|
-
# def throwaway_id
|
65
|
-
# @throwaway_id = (@throwaway_id ? @throwaway_id + 1 : 0)
|
66
|
-
# end
|
67
|
-
#
|
68
|
-
# def all
|
69
|
-
# ObjectSpace.each_object(self)
|
70
|
-
# end
|
71
|
-
#
|
72
|
-
# def find(ids)
|
73
|
-
# all.select{|instance| ids.include?(instance.id.to_s) }
|
74
|
-
# end
|
75
|
-
# end
|
76
|
-
#end
|
77
|
-
|
78
|
-
describe 'Tanker integration tests with IndexTank' do
|
79
|
-
|
80
|
-
before(:all) do
|
37
|
+
describe 'An imaginary store' do
|
38
|
+
|
39
|
+
before(:all) do
|
81
40
|
Tanker::Utilities.clear_index('tanker_integration_tests')
|
82
|
-
|
83
|
-
|
84
|
-
@
|
85
|
-
@
|
86
|
-
|
41
|
+
|
42
|
+
# Google products
|
43
|
+
@blackberry = Product.create(:name => 'blackberry', :href => "google", :tags => ['decent', 'businessmen love it'])
|
44
|
+
@nokia = Product.create(:name => 'nokia', :href => "google", :tags => ['decent'])
|
45
|
+
|
46
|
+
# Amazon products
|
47
|
+
@android = Product.create(:name => 'android', :href => "amazon", :tags => ['awesome'])
|
48
|
+
@samsung = Product.create(:name => 'samsung', :href => "amazon", :tags => ['decent'])
|
49
|
+
@motorola = Product.create(:name => 'motorola', :href => "amazon", :tags => ['decent'],
|
50
|
+
:description => "Not sure about features since I've never owned one.")
|
51
|
+
|
52
|
+
# Ebay products
|
53
|
+
@palmpre = Product.create(:name => 'palmpre', :href => "ebay", :tags => ['discontinued', 'worst phone ever'])
|
54
|
+
@palm_pixi_plus = Product.create(:name => 'palm pixi plus', :href => "ebay", :tags => ['terrible'])
|
55
|
+
@lg_vortex = Product.create(:name => 'lg vortex', :href => "ebay", :tags => ['decent'])
|
56
|
+
@t_mobile = Product.create(:name => 't mobile', :href => "ebay", :tags => ['terrible'])
|
57
|
+
|
58
|
+
# Yahoo products
|
59
|
+
@htc = Product.create(:name => 'htc', :href => "yahoo", :tags => ['decent'])
|
60
|
+
@htc_evo = Product.create(:name => 'htc evo', :href => "yahoo", :tags => ['decent'])
|
61
|
+
@ericson = Product.create(:name => 'ericson', :href => "yahoo", :tags => ['decent'])
|
62
|
+
|
63
|
+
# Apple products
|
64
|
+
@iphone = Product.create(:name => 'iphone', :href => "apple", :tags => ['awesome', 'poor reception'],
|
65
|
+
:description => 'Puts even more features at your fingertips')
|
66
|
+
|
67
|
+
@products_in_database = Product.all
|
68
|
+
|
87
69
|
Product.tanker_reindex
|
88
70
|
end
|
89
71
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
@prod_3.delete_tank_indexes
|
154
|
-
end
|
155
|
-
|
156
|
-
it 'should fetch attribute requested from Index Tank and create an intstance of the Model without calling the database' do
|
157
|
-
@results = Product.search_tank('something', :fetch => [:name])
|
158
|
-
@results.count.should == 1
|
159
|
-
|
160
|
-
@new_prod_instance = @results[0]
|
161
|
-
@new_prod_instance.name.should == 'something small'
|
162
|
-
end
|
163
|
-
|
164
|
-
it 'should get a snippet for an attribute requested from Index Tank and create an intstance of the Model without calling the database and with a _snippet attribute reader' do
|
165
|
-
@results = Product.search_tank('product', :snippets => [:name])
|
166
|
-
@results.count.should == 1
|
167
|
-
|
168
|
-
@new_prod_instance = @results[0]
|
169
|
-
@new_prod_instance.name_snippet.should =~ /<b>product<\/b>/
|
170
|
-
end
|
171
|
-
|
172
|
-
it 'should create a new instance of a model and fetch attributes that where requested and get snippets for the attributes required as snippets' do
|
173
|
-
@results = Product.search_tank('quis exercitation', :snippets => [:name], :fetch => [:href])
|
174
|
-
@results.count.should == 1
|
175
|
-
|
176
|
-
@new_prod_instance = @results[0]
|
177
|
-
@new_prod_instance.name_snippet.should =~ /<b>quis<\/b>/
|
178
|
-
@new_prod_instance.href.should == 'http://google.com'
|
179
|
-
end
|
180
|
-
end
|
72
|
+
describe 'basic searching' do
|
73
|
+
|
74
|
+
it 'should find all amazon products' do
|
75
|
+
results = Product.search_tank('amazon')
|
76
|
+
results.should include(@android, @samsung, @motorola)
|
77
|
+
results.should have_exactly(3).products
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should find the iphone' do
|
81
|
+
results = Product.search_tank('iphone')
|
82
|
+
results.should include(@iphone)
|
83
|
+
results.should have_exactly(1).product
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should find all "palm" phones with wildcard word search' do
|
87
|
+
results = Product.search_tank('palm*')
|
88
|
+
results.should include(@palmpre, @palm_pixi_plus)
|
89
|
+
results.should have_exactly(2).products
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should search multiple words from the same field' do
|
93
|
+
results = Product.search_tank('palm pixi plus')
|
94
|
+
results.should include(@palm_pixi_plus)
|
95
|
+
results.should have_exactly(1).product
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should narrow the results by searching across multiple fields" do
|
99
|
+
results = Product.search_tank('apple iphone')
|
100
|
+
results.should include(@iphone)
|
101
|
+
results.should have(1).product
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should serach case insensitively" do
|
105
|
+
results = Product.search_tank('IPHONE')
|
106
|
+
results.should include(@iphone)
|
107
|
+
results.should have(1).product
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe 'searching by tag' do
|
112
|
+
it 'should find all "awesome" products regardless of other attributes' do
|
113
|
+
results = Product.search_tank('', :conditions => {:tags => 'awesome'})
|
114
|
+
results.should include(@android, @iphone)
|
115
|
+
results.should have_exactly(2).products
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should find all "decent" products sold by amazon' do
|
119
|
+
results = Product.search_tank('amazon', :conditions => {:tags => 'decent'})
|
120
|
+
results.should include(@samsung, @motorola)
|
121
|
+
results.should have_exactly(2).products
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should find all "terrible" or "discontinued" products sold by ebay' do
|
125
|
+
results = Product.search_tank('ebay', :conditions => {:tags => 'terrible OR discontinued'})
|
126
|
+
results.should include(@t_mobile, @palmpre, @palm_pixi_plus)
|
127
|
+
results.should have_exactly(3).products
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should find products tagged as "discontinued" and "worst phone ever" sold by ebay' do
|
131
|
+
results = Product.search_tank('ebay', :conditions => {:tags => ['discontinued', 'worst phone ever']})
|
132
|
+
results.should include(@palmpre)
|
133
|
+
results.should have_exactly(1).product
|
134
|
+
end
|
181
135
|
end
|
136
|
+
|
137
|
+
describe "negative search conditions" do
|
138
|
+
|
139
|
+
it 'should find all "awesome" products excluding those sold by apple' do
|
140
|
+
results = Product.search_tank('awesome', :conditions => {'-href' => 'apple'})
|
141
|
+
results.should include(@android)
|
142
|
+
results.should have_exactly(1).product
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'should find all "awesome" products excluding those sold by apple (using alternate syntax)' do
|
146
|
+
results = Product.search_tank('awesome', :conditions => {'NOT href' => 'apple'})
|
147
|
+
results.should include(@android)
|
148
|
+
results.should have_exactly(1).product
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should find all "decent" products excluding those sold by apple (using alternate syntax)' do
|
152
|
+
results = Product.search_tank('awesome', :conditions => {'NOT href' => 'apple'})
|
153
|
+
results.should include(@android)
|
154
|
+
results.should have_exactly(1).product
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'should find the "htc" but not the "htc evo"' do
|
158
|
+
results = Product.search_tank('htc NOT evo')
|
159
|
+
results.should include(@htc)
|
160
|
+
results.should have_exactly(1).product
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "fetching products (as opposed to searching)" do
|
165
|
+
|
166
|
+
before { @results = Product.search_tank('apple', :fetch => [:name]) }
|
167
|
+
|
168
|
+
it 'should find all "apple" products' do
|
169
|
+
@results.should have_exactly(1).product
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should set values only for the fetched attributes" do
|
173
|
+
@results.first.name.should == 'iphone'
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should set any non-fetched attributes to nil" do
|
177
|
+
@results.first.href.should be_nil
|
178
|
+
@results.first.tags.should be_nil
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should build results from the index without touching the database" do
|
182
|
+
@products_in_database.should_not include(@results)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "searching snippets" do
|
187
|
+
before(:all) { @results = Product.search_tank('features', :snippets => [:description]) }
|
188
|
+
|
189
|
+
it 'should find snippets for any product with "features" in the description' do
|
190
|
+
@results.should have_exactly(2).products # motorola and iphone
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should build results from the index without touching the database" do
|
194
|
+
@products_in_database.should_not include(@results)
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'should dynamically create an "<attribute>_snippet" method for each result' do
|
198
|
+
@results.each { |r| r.should respond_to(:description_snippet) }
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'should return a snippet for iphone' do
|
202
|
+
snippets = @results.map(&:description_snippet)
|
203
|
+
snippets.should include("Puts even more <b>features</b> at your fingertips")
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'should return a snippet for motorola' do
|
207
|
+
snippets = @results.map(&:description_snippet)
|
208
|
+
snippets.should include("Not sure about <b>features</b> since I've never owned one")
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe "searching snippets while also fetching specific attributes" do
|
213
|
+
before :all do
|
214
|
+
@results = Product.search_tank('features', :snippets => [:description], :fetch => [:name, :href])
|
215
|
+
@indexed_iphone = @results.detect { |r| r.name == 'iphone' }
|
216
|
+
@indexed_motorola = @results.detect { |r| r.name == 'motorola' }
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'should find any product with "features" in the description' do
|
220
|
+
@results.should include(@indexed_motorola, @indexed_iphone)
|
221
|
+
@results.should have_exactly(2).products
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should build results from the index without touching the database" do
|
225
|
+
@products_in_database.should_not include(@results)
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'should set the "name" attribute for all results' do
|
229
|
+
@indexed_motorola.name.should == 'motorola'
|
230
|
+
@indexed_iphone.name.should == 'iphone'
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'should set the "href" attribute for all results' do
|
234
|
+
@indexed_motorola.href.should == 'amazon'
|
235
|
+
@indexed_iphone.href.should == 'apple'
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'should set the "description_snippet" attribute for all results' do
|
239
|
+
@indexed_motorola.description_snippet.should == "Not sure about <b>features</b> since I've never owned one"
|
240
|
+
@indexed_iphone.description_snippet.should == "Puts even more <b>features</b> at your fingertips"
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
182
244
|
end
|
183
245
|
|
data/spec/tanker_spec.rb
CHANGED
@@ -249,7 +249,7 @@ describe Tanker do
|
|
249
249
|
|
250
250
|
it 'should be able to use multi-value query phrases' do
|
251
251
|
Person.tanker_index.should_receive(:search).with(
|
252
|
-
'name:(hey! location_id:(1) location_id:(2)) OR last_name:(hey! location_id:(1) location_id:(2)) __type:("Person")',
|
252
|
+
'name:(hey! location_id:(1) location_id:(2)) OR last_name:(hey! location_id:(1) location_id:(2)) OR __any:(hey! location_id:(1) location_id:(2)) __type:("Person")',
|
253
253
|
anything
|
254
254
|
).and_return({'results' => [], 'matches' => 0})
|
255
255
|
|
@@ -500,9 +500,9 @@ describe Tanker do
|
|
500
500
|
end
|
501
501
|
|
502
502
|
# Need to do this for tests to pass on 1.8.7. If not tanker.rb is
|
503
|
-
# reloaded Tanker::
|
503
|
+
# reloaded Tanker::Pagination::Kaminari const gets removed (!?)
|
504
504
|
before :each do
|
505
|
-
load 'tanker.rb'
|
505
|
+
load 'tanker/pagination.rb'
|
506
506
|
end
|
507
507
|
|
508
508
|
it 'should raise error message if Kaminari gem is not required' do
|
@@ -541,7 +541,7 @@ describe Tanker do
|
|
541
541
|
Person.should_receive(:find).and_return([Person.new])
|
542
542
|
|
543
543
|
array = Person.search_tank('hey!')
|
544
|
-
array.class.should == Tanker::
|
544
|
+
array.class.should == Tanker::Pagination::Kaminari
|
545
545
|
array.total_count.should == 1
|
546
546
|
array.num_pages.should == 1
|
547
547
|
array.limit_value.should == 10
|
data/tanker.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{tanker}
|
8
|
-
s.version = "1.1.
|
8
|
+
s.version = "1.1.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = [%q{Francisco Viramontes}, %q{Jack Danger Canty}]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-07-01}
|
13
13
|
s.description = %q{IndexTank is a great search indexing service, this gem tries to make any orm keep in sync with indextank with ease}
|
14
14
|
s.email = %q{kidpollo@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -27,7 +27,9 @@ Gem::Specification.new do |s|
|
|
27
27
|
"lib/indextank_client.rb",
|
28
28
|
"lib/tanker.rb",
|
29
29
|
"lib/tanker/configuration.rb",
|
30
|
-
"lib/tanker/
|
30
|
+
"lib/tanker/pagination.rb",
|
31
|
+
"lib/tanker/pagination/kaminari.rb",
|
32
|
+
"lib/tanker/pagination/will_paginate.rb",
|
31
33
|
"lib/tanker/railtie.rb",
|
32
34
|
"lib/tanker/tasks/tanker.rake",
|
33
35
|
"lib/tanker/utilities.rb",
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: tanker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.1.
|
5
|
+
version: 1.1.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Francisco Viramontes
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2011-
|
14
|
+
date: 2011-07-01 00:00:00 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: json
|
@@ -77,7 +77,9 @@ files:
|
|
77
77
|
- lib/indextank_client.rb
|
78
78
|
- lib/tanker.rb
|
79
79
|
- lib/tanker/configuration.rb
|
80
|
-
- lib/tanker/
|
80
|
+
- lib/tanker/pagination.rb
|
81
|
+
- lib/tanker/pagination/kaminari.rb
|
82
|
+
- lib/tanker/pagination/will_paginate.rb
|
81
83
|
- lib/tanker/railtie.rb
|
82
84
|
- lib/tanker/tasks/tanker.rake
|
83
85
|
- lib/tanker/utilities.rb
|
@@ -1,30 +0,0 @@
|
|
1
|
-
unless defined?(Kaminari)
|
2
|
-
raise(Tanker::BadConfiguration, "Tanker: Please add 'kaminari' to your Gemfile to use kaminari pagination backend")
|
3
|
-
end
|
4
|
-
|
5
|
-
module Tanker
|
6
|
-
class KaminariPaginatedArray < Array
|
7
|
-
include ::Kaminari::ConfigurationMethods::ClassMethods
|
8
|
-
include ::Kaminari::PageScopeMethods
|
9
|
-
|
10
|
-
attr_reader :limit_value, :offset_value, :total_count
|
11
|
-
|
12
|
-
def initialize(original_array, limit_val, offset_val, total_count)
|
13
|
-
@limit_value = limit_val || default_per_page
|
14
|
-
@offset_value, @total_count = offset_val, total_count
|
15
|
-
super(original_array)
|
16
|
-
end
|
17
|
-
|
18
|
-
def page(num = 1)
|
19
|
-
self
|
20
|
-
end
|
21
|
-
|
22
|
-
def limit(num)
|
23
|
-
self
|
24
|
-
end
|
25
|
-
|
26
|
-
def current_page
|
27
|
-
offset_value+1
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|