tanker 1.1.2 → 1.1.3
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/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
|