algoliasearch-rails 1.14.1 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,35 +1,43 @@
1
+ <!--NO_HTML-->
2
+
1
3
  Algolia Search for Rails
2
4
  ==================
3
5
 
4
- This gem let you easily integrate the Algolia Search API to your favorite ORM. It's based on the [algoliasearch-client-ruby](https://github.com/algolia/algoliasearch-client-ruby) gem. Both Rails 3.x and Rails 4.x are supported.
6
+ <!--/NO_HTML-->
7
+
8
+ This gem let you easily integrate the Algolia Search API to your favorite ORM. It's based on the [algoliasearch-client-ruby](https://github.com/algolia/algoliasearch-client-ruby) gem. Rails 3.x, 4.x and 5.x are all supported.
5
9
 
6
- You might be interested in the sample Ruby on Rails application providing a ```typeahead.js```-based auto-completion and ```Google```-like instant search: [algoliasearch-rails-example](https://github.com/algolia/algoliasearch-rails-example/).
10
+ You might be interested in the sample Ruby on Rails application providing a ```autocomplete.js```-based auto-completion and ```instantsearch.js```-based instant search results page: [algoliasearch-rails-example](https://github.com/algolia/algoliasearch-rails-example/).
7
11
 
8
- [![Build Status](https://travis-ci.org/algolia/algoliasearch-rails.png?branch=master)](https://travis-ci.org/algolia/algoliasearch-rails) [![Gem Version](https://badge.fury.io/rb/algoliasearch-rails.png)](http://badge.fury.io/rb/algoliasearch-rails) [![Code Climate](https://codeclimate.com/github/algolia/algoliasearch-rails.png)](https://codeclimate.com/github/algolia/algoliasearch-rails) ![ActiveRecord](https://img.shields.io/badge/ActiveRecord-yes-blue.svg?style=flat-square) ![Mongoid](https://img.shields.io/badge/Mongoid-yes-blue.svg?style=flat-square) ![Sequel](https://img.shields.io/badge/Sequel-yes-blue.svg?style=flat-square)
12
+ [![Build Status](https://travis-ci.org/algolia/algoliasearch-rails.svg?branch=master)](https://travis-ci.org/algolia/algoliasearch-rails) [![Gem Version](https://badge.fury.io/rb/algoliasearch-rails.svg)](http://badge.fury.io/rb/algoliasearch-rails) [![Code Climate](https://codeclimate.com/github/algolia/algoliasearch-rails.svg)](https://codeclimate.com/github/algolia/algoliasearch-rails) ![ActiveRecord](https://img.shields.io/badge/ActiveRecord-yes-blue.svg?style=flat-square) ![Mongoid](https://img.shields.io/badge/Mongoid-yes-blue.svg?style=flat-square) ![Sequel](https://img.shields.io/badge/Sequel-yes-blue.svg?style=flat-square)
13
+
14
+ <!--NO_HTML-->
9
15
 
10
16
  Table of Content
11
- -------------
12
- **Get started**
17
+ =============
13
18
 
14
19
  1. [Install](#install)
15
20
  1. [Setup](#setup)
16
21
  1. [Quick Start](#quick-start)
17
- 1. [Ranking & Relevance](#ranking--relevance)
18
22
  1. [Options](#options)
19
23
  1. [Configuration example](#configuration-example)
20
24
  1. [Indexing](#indexing)
21
25
  1. [Master/Slave](#masterslave)
26
+ 1. [Share a single index](#share-a-single-index)
22
27
  1. [Target multiple indexes](#target-multiple-indexes)
23
28
  1. [Tags](#tags)
24
29
  1. [Search](#search)
25
30
  1. [Faceting](#faceting)
31
+ 1. [Group by](#group-by)
26
32
  1. [Geo-search](#geo-search)
27
- 1. [Typeahead UI](#typeahead-ui)
28
33
  1. [Caveats](#caveats)
29
34
  1. [Note on testing](#note-on-testing)
30
35
 
31
- Install
32
- -------------
36
+ <!--/NO_HTML-->
37
+
38
+ ## Setup
39
+
40
+ ### Install
33
41
 
34
42
  ```sh
35
43
  gem install algoliasearch-rails
@@ -47,8 +55,8 @@ And run:
47
55
  bundle install
48
56
  ```
49
57
 
50
- Setup
51
- -------------
58
+ ### Configuration
59
+
52
60
  Create a new file <code>config/initializers/algoliasearch.rb</code> to setup your <code>APPLICATION_ID</code> and <code>API_KEY</code>.
53
61
 
54
62
 
@@ -58,14 +66,9 @@ AlgoliaSearch.configuration = { application_id: 'YourApplicationID', api_key: 'Y
58
66
 
59
67
  The gem is compatible with [ActiveRecord](https://github.com/rails/rails/tree/master/activerecord), [Mongoid](https://github.com/mongoid/mongoid) and [Sequel](https://github.com/jeremyevans/sequel).
60
68
 
61
- We support both [will_paginate](https://github.com/mislav/will_paginate) and [kaminari](https://github.com/amatsuda/kaminari) as pagination backend. For example to use <code>:will_paginate</code>, specify the <code>:pagination_backend</code> as follow:
62
-
63
- ```ruby
64
- AlgoliaSearch.configuration = { application_id: 'YourApplicationID', api_key: 'YourAPIKey', pagination_backend: :will_paginate }
65
- ```
69
+ ## Quick Start
66
70
 
67
- Quick Start
68
- -------------
71
+ ### Schema
69
72
 
70
73
  The following code will create a <code>Contact</code> index and add search capabilities to your <code>Contact</code> model:
71
74
 
@@ -108,7 +111,7 @@ class Product < ActiveRecord::Base
108
111
  end
109
112
  ```
110
113
 
111
- #### Ranking & Relevance
114
+ ### Relevancy
112
115
 
113
116
  We provide many ways to configure your index allowing you to tune your overall index relevancy. The most important ones are the **searchable attributes** and the attributes reflecting **record popularity**.
114
117
 
@@ -134,7 +137,25 @@ class Product < ActiveRecord::Base
134
137
  end
135
138
  ```
136
139
 
137
- #### Frontend Search (realtime experience)
140
+ ### Indexing
141
+
142
+ To index a model, simple call `reindex` on the class:
143
+
144
+ ```ruby
145
+ Product.reindex
146
+ ```
147
+
148
+ To index all of your models, you can do something like this:
149
+
150
+ ```ruby
151
+ Rails.application.eager_load! # Ensure all models are loaded (required in development).
152
+
153
+ algolia_models = ActiveRecord::Base.descendants.select{ |model| model.respond_to?(:reindex) }
154
+
155
+ algolia_models.each(&:reindex)
156
+ ```
157
+
158
+ ### Frontend Search (realtime experience)
138
159
 
139
160
  Traditional search implementations tend to have search logic and functionality on the backend. This made sense when the search experience consisted of a user entering a search query, executing that search, and then being redirected to a search result page.
140
161
 
@@ -151,14 +172,18 @@ Then in your JavaScript code you can do:
151
172
  ```js
152
173
  var client = algoliasearch(ApplicationID, Search-Only-API-Key);
153
174
  var index = client.initIndex('YourIndexName');
154
- index.search('something', function(success, hits) {
155
- console.log(success, hits)
156
- }, { hitsPerPage: 10, page: 0 });
175
+ index.search('something', { hitsPerPage: 10, page: 0 })
176
+ .then(function searchDone(content) {
177
+ console.log(content)
178
+ })
179
+ .catch(function searchFailure(err) {
180
+ console.error(err);
181
+ });
157
182
  ```
158
183
 
159
184
  **We recently (March 2015) released a new version (V3) of our JavaScript client, if you were using our previous version (V2), [read the migration guide](https://github.com/algolia/algoliasearch-client-js/wiki/Migration-guide-from-2.x.x-to-3.x.x)**
160
185
 
161
- #### Backend Search
186
+ ### Backend Search
162
187
 
163
188
  If you want to search from your backend you can use the `raw_search` method. It retrieves the raw JSON answer from the API:
164
189
 
@@ -172,7 +197,31 @@ You could also use `search` but it's not recommended. This method will fetch the
172
197
  p Contact.search("jon doe") # we recommend to use `raw_search` to avoid the database lookup
173
198
  ```
174
199
 
175
- #### Notes
200
+ ### Backend Pagination
201
+
202
+ Even if we **highly recommend to perform all search (and therefore pagination) operations from your frontend using JavaScript**, we support both [will_paginate](https://github.com/mislav/will_paginate) and [kaminari](https://github.com/amatsuda/kaminari) as pagination backend.
203
+
204
+ To use <code>:will_paginate</code>, specify the <code>:pagination_backend</code> as follow:
205
+
206
+ ```ruby
207
+ AlgoliaSearch.configuration = { application_id: 'YourApplicationID', api_key: 'YourAPIKey', pagination_backend: :will_paginate }
208
+ ```
209
+
210
+ Then, as soon as you use the `search` method, the returning results will be a paginated set:
211
+
212
+ ```ruby
213
+ # in your controller
214
+ @results = MyModel.search('foo', hitsPerPage: 10)
215
+
216
+ # in your views
217
+ # if using will_paginate
218
+ <%= will_paginate @results %>
219
+
220
+ # if using kaminari
221
+ <%= paginate @results %>
222
+ ```
223
+
224
+ ### Notes
176
225
 
177
226
  All methods injected by the ```AlgoliaSearch``` include are prefixed by ```algolia_``` and aliased to the associated short names if they aren't already defined.
178
227
 
@@ -182,10 +231,9 @@ Contact.algolia_reindex! # <=> Contact.reindex!
182
231
  Contact.algolia_search("jon doe") # <=> Contact.search("jon doe")
183
232
  ```
184
233
 
185
- Options
186
- ----------
234
+ ## Options
187
235
 
188
- #### Auto-indexing & asynchronism
236
+ ### Auto-indexing & asynchronism
189
237
 
190
238
  Each time a record is saved; it will be - asynchronously - indexed. On the other hand, each time a record is destroyed, it will be - asynchronously - removed from the index. That means that a network call with the ADD/DELETE operation is sent **synchronously** to the Algolia API but then the engine will **asynchronously** process the operation (so if you do a search just after, the results may not reflect it yet).
191
239
 
@@ -201,7 +249,7 @@ class Contact < ActiveRecord::Base
201
249
  end
202
250
  ```
203
251
 
204
- ##### Temporary disable auto-indexing
252
+ #### Temporary disable auto-indexing
205
253
 
206
254
  You can temporary disable auto-indexing using the <code>without_auto_index</code> scope. This is often used for performance reason.
207
255
 
@@ -213,7 +261,7 @@ end
213
261
  Contact.reindex! # will use batch operations
214
262
  ```
215
263
 
216
- ##### Queues & background jobs
264
+ #### Queues & background jobs
217
265
 
218
266
  You can configure the auto-indexing & auto-removal process to use a queue to perform those operations in background. ActiveJob (Rails >=4.2) queues are used by default but you can define your own queuing mechanism:
219
267
 
@@ -227,7 +275,31 @@ class Contact < ActiveRecord::Base
227
275
  end
228
276
  ```
229
277
 
230
- ##### With Sidekiq
278
+ #### Things to Consider
279
+
280
+ If you are performing updates & deletions in the background then a record deletion can be committed to your database prior
281
+ to the job actually executing. Thus if you were to load the record to remove it from the database than your ActiveRecord#find will fail with a RecordNotFound.
282
+
283
+ In this case you can bypass loading the record from ActiveRecord and just communicate with the index directly:
284
+
285
+ ```ruby
286
+ class MySidekiqWorker
287
+ def perform(id, remove)
288
+ if remove
289
+ # the record has likely already been removed from your database so we cannot
290
+ # use ActiveRecord#find to load it
291
+ index = Algolia::Index.new("index_name")
292
+ index.delete_object(id)
293
+ else
294
+ # the record should be present
295
+ c = Contact.find(id)
296
+ c.index!
297
+ end
298
+ end
299
+ end
300
+ ```
301
+
302
+ #### With Sidekiq
231
303
 
232
304
  If you're using [Sidekiq](https://github.com/mperham/sidekiq):
233
305
 
@@ -252,7 +324,7 @@ class MySidekiqWorker
252
324
  end
253
325
  ```
254
326
 
255
- ##### With DelayedJob
327
+ #### With DelayedJob
256
328
 
257
329
  If you're using [delayed_job](https://github.com/collectiveidea/delayed_job):
258
330
 
@@ -275,7 +347,7 @@ end
275
347
 
276
348
  ```
277
349
 
278
- ##### Synchronism & testing
350
+ #### Synchronism & testing
279
351
 
280
352
  You can force indexing and removing to be synchronous (in that case the gem will call the `wait_task` method to ensure the operation has been taken into account once the method returns) by setting the following option: (this is **NOT** recommended, except for testing purpose)
281
353
 
@@ -289,7 +361,7 @@ class Contact < ActiveRecord::Base
289
361
  end
290
362
  ```
291
363
 
292
- #### Exceptions
364
+ ### Exceptions
293
365
 
294
366
  You can disable exceptions that could be raised while trying to reach Algolia's API by using the `raise_on_failure` option:
295
367
 
@@ -304,7 +376,7 @@ class Contact < ActiveRecord::Base
304
376
  end
305
377
  ```
306
378
 
307
- #### Custom index name
379
+ ### Custom index name
308
380
 
309
381
  By default, the index name will be the class name, e.g. "Contact". You can customize the index name by using the `index_name` option:
310
382
 
@@ -318,7 +390,7 @@ class Contact < ActiveRecord::Base
318
390
  end
319
391
  ```
320
392
 
321
- #### Per-environment indexes
393
+ ### Per-environment indexes
322
394
 
323
395
  You can suffix the index name with the current Rails environment using the following option:
324
396
 
@@ -332,7 +404,7 @@ class Contact < ActiveRecord::Base
332
404
  end
333
405
  ```
334
406
 
335
- #### Custom attribute definition
407
+ ### Custom attribute definition
336
408
 
337
409
  You can use a block to specify a complex attribute value
338
410
 
@@ -373,7 +445,7 @@ class Contact < ActiveRecord::Base
373
445
  end
374
446
  ```
375
447
 
376
- #### Nested objects/relations
448
+ ### Nested objects/relations
377
449
 
378
450
  You can easily embed nested objects defining an extra attribute returning any JSON-compliant object (an array or a hash or a combination of both).
379
451
 
@@ -400,7 +472,7 @@ class Profile < ActiveRecord::Base
400
472
  end
401
473
  ```
402
474
 
403
- #### Custom ```objectID```
475
+ ### Custom ```objectID```
404
476
 
405
477
  By default, the `objectID` is based on your record's `id`. You can change this behavior specifying the `:id` option (be sure to use a uniq field).
406
478
 
@@ -413,10 +485,12 @@ class UniqUser < ActiveRecord::Base
413
485
  end
414
486
  ```
415
487
 
416
- #### Restrict indexing to a subset of your data
488
+ ### Restrict indexing to a subset of your data
417
489
 
418
490
  You can add constraints controlling if a record must be indexed by using options the ```:if``` or ```:unless``` options.
419
491
 
492
+ It allows you to do conditional indexing on a per document basis.
493
+
420
494
  ```ruby
421
495
  class Post < ActiveRecord::Base
422
496
  include AlgoliaSearch
@@ -467,7 +541,7 @@ or
467
541
  MyModel.index_objects MyModel.limit(5)
468
542
  ```
469
543
 
470
- #### Sanitizer
544
+ ### Sanitizer
471
545
 
472
546
  You can sanitize all your attributes using the ```sanitize``` option. It will strip all HTML tags from your attributes.
473
547
 
@@ -489,7 +563,7 @@ gem 'rails-html-sanitizer'
489
563
  ```
490
564
 
491
565
 
492
- #### UTF-8 Encoding
566
+ ### UTF-8 Encoding
493
567
 
494
568
  You can force the UTF-8 encoding of all your attributes using the ```force_utf8_encoding``` option:
495
569
 
@@ -507,8 +581,7 @@ end
507
581
  ***Notes:*** This option is not compatible with Ruby 1.8
508
582
 
509
583
 
510
- Configuration example
511
- ---------------------
584
+ ### Configuration example
512
585
 
513
586
  Here is a real-word configuration example (from [HN Search](https://github.com/algolia/hn-search)):
514
587
 
@@ -565,10 +638,9 @@ class Item < ActiveRecord::Base
565
638
  end
566
639
  ```
567
640
 
568
- Indexing
569
- ---------
641
+ ## Indexing
570
642
 
571
- #### Manual indexing
643
+ ### Manual indexing
572
644
 
573
645
  You can trigger indexing using the <code>index!</code> instance method.
574
646
 
@@ -577,7 +649,7 @@ c = Contact.create!(params[:contact])
577
649
  c.index!
578
650
  ```
579
651
 
580
- #### Manual removal
652
+ ### Manual removal
581
653
 
582
654
  And trigger index removing using the <code>remove_from_index!</code> instance method.
583
655
 
@@ -586,21 +658,29 @@ c.remove_from_index!
586
658
  c.destroy
587
659
  ```
588
660
 
589
- #### Reindexing
661
+ ### Reindexing
662
+
663
+ The gem provides 2 ways to reindex all your objects:
664
+
665
+ #### Atomical reindexing
590
666
 
591
- To *safely* reindex all your records (index to a temporary index + move the temporary index to the current one atomically), use the <code>reindex</code> class method:
667
+ To reindex all your records (taking into account the deleted objects), the `reindex` class method indexes all your objects to a temporary index called `<INDEX_NAME>.tmp` and moves the temporary index to the final one once everything is indexed (atomically). This is the safest way to reindex all your content.
592
668
 
593
669
  ```ruby
594
670
  Contact.reindex
595
671
  ```
596
672
 
597
- To reindex all your records (in place, without deleting out-dated records), use the <code>reindex!</code> class method:
673
+ **Notes**: if you're using an index-specific API key, ensure you're allowing both `<INDEX_NAME>` and `<INDEX_NAME>.tmp`.
674
+
675
+ #### Regular reindexing
676
+
677
+ To reindex all your objects in place (without temporary index and therefore without deleting removed objects), use the `reindex!` class method:
598
678
 
599
679
  ```ruby
600
680
  Contact.reindex!
601
681
  ```
602
682
 
603
- #### Clearing an index
683
+ ### Clearing an index
604
684
 
605
685
  To clear an index, use the <code>clear_index!</code> class method:
606
686
 
@@ -608,7 +688,7 @@ To clear an index, use the <code>clear_index!</code> class method:
608
688
  Contact.clear_index!
609
689
  ```
610
690
 
611
- #### Using the underlying index
691
+ ### Using the underlying index
612
692
 
613
693
  You can access the underlying `index` object by calling the `index` class method:
614
694
 
@@ -617,8 +697,9 @@ index = Contact.index
617
697
  # index.get_settings, index.partial_update_object, ...
618
698
  ```
619
699
 
620
- Master/slave
621
- ---------
700
+ ## Indexes
701
+
702
+ ### Master/slave
622
703
 
623
704
  You can define slave indexes using the <code>add_slave</code> method:
624
705
 
@@ -653,8 +734,45 @@ Book.raw_search 'foo bar', slave: 'Book_by_editor'
653
734
  Book.search 'foo bar', slave: 'Book_by_editor'
654
735
  ```
655
736
 
656
- Target multiple indexes
657
- ---------
737
+ ### Share a single index
738
+
739
+ It can make sense to share an index between several models. In order to implement that, you'll need to ensure you don't have any conflict with the `objectID` of the underlying models.
740
+
741
+ ```ruby
742
+ class Student < ActiveRecord::Base
743
+ attr_protected
744
+
745
+ include AlgoliaSearch
746
+
747
+ algoliasearch index_name: 'people', id: :algolia_id do
748
+ # [...]
749
+ end
750
+
751
+ private
752
+ def algolia_id
753
+ "student_#{id}" # ensure the teacher & student IDs are not conflicting
754
+ end
755
+ end
756
+
757
+ class Teacher < ActiveRecord::Base
758
+ attr_protected
759
+
760
+ include AlgoliaSearch
761
+
762
+ algoliasearch index_name: 'people', id: :algolia_id do
763
+ # [...]
764
+ end
765
+
766
+ private
767
+ def algolia_id
768
+ "teacher_#{id}" # ensure the teacher & student IDs are not conflicting
769
+ end
770
+ end
771
+ ```
772
+
773
+ ***Notes:*** If you target a single index from several models, you must never use `MyModel.reindex` and only use `MyModel.reindex!`. The `reindex` method uses a temporary index to perform an atomic reindexing: if you use it, the resulting index will only contain records for the current model because it will not reindex the others.
774
+
775
+ ### Target multiple indexes
658
776
 
659
777
  You can index a record in several indexes using the <code>add_index</code> method:
660
778
 
@@ -667,7 +785,7 @@ class Book < ActiveRecord::Base
667
785
  PUBLIC_INDEX_NAME = "Book_#{Rails.env}"
668
786
  SECURED_INDEX_NAME = "SecuredBook_#{Rails.env}"
669
787
 
670
- # store all books in index 'SECURED_INDEX_NAME'
788
+ # store all books in index 'SECURED_INDEX_NAME'
671
789
  algoliasearch index_name: SECURED_INDEX_NAME do
672
790
  attributesToIndex [:name, :author]
673
791
  # convert security to tags
@@ -697,8 +815,9 @@ Book.raw_search 'foo bar', index: 'Book_by_editor'
697
815
  Book.search 'foo bar', index: 'Book_by_editor'
698
816
  ```
699
817
 
700
- Tags
701
- -----
818
+ ## Features
819
+
820
+ ### Tags
702
821
 
703
822
  Use the <code>tags</code> method to add tags to your record:
704
823
 
@@ -728,8 +847,7 @@ end
728
847
 
729
848
  At query time, specify <code>{ tagFilters: 'tagvalue' }</code> or <code>{ tagFilters: ['tagvalue1', 'tagvalue2'] }</code> as search parameters to restrict the result set to specific tags.
730
849
 
731
- Search
732
- ----------
850
+ ### Search
733
851
 
734
852
  ***Notes:*** We recommend the usage of our [JavaScript API Client](https://github.com/algolia/algoliasearch-client-js) to perform queries directly from the end-user browser without going through your server.
735
853
 
@@ -765,7 +883,7 @@ class Contact < ActiveRecord::Base
765
883
 
766
884
  algoliasearch do
767
885
  attribute :first_name, :last_name, :email
768
-
886
+
769
887
  # default search parameters stored in the index settings
770
888
  minWordSizeForApprox1 4
771
889
  minWordSizeForApprox2 8
@@ -779,8 +897,7 @@ end
779
897
  p Contact.raw_search("jon doe", { :hitsPerPage => 5, :page => 2 })
780
898
  ```
781
899
 
782
- Faceting
783
- ---------
900
+ ### Faceting
784
901
 
785
902
  Facets can be retrieved calling the extra ```facets``` method of the search answer.
786
903
 
@@ -810,68 +927,46 @@ raw_json = Contact.raw_search("jon doe", { :facets => '*' })
810
927
  p raw_json['facets']
811
928
  ```
812
929
 
813
- Geo-Search
814
- -----------
930
+ ### Group by
815
931
 
816
- Use the <code>geoloc</code> method to localize your record:
932
+ More info on distinct for grouping can be found
933
+ [here](https://www.algolia.com/doc/guides/search/distinct#distinct-for-grouping).
817
934
 
818
935
  ```ruby
819
936
  class Contact < ActiveRecord::Base
820
937
  include AlgoliaSearch
821
938
 
822
939
  algoliasearch do
823
- geoloc :lat_attr, :lng_attr
940
+ # [...]
941
+
942
+ # specify the attribute to be used for distinguishing the records
943
+ # in this case the records will be grouped by company
944
+ attributeForDistinct "company"
824
945
  end
825
946
  end
826
947
  ```
827
948
 
828
- At query time, specify <code>{ aroundLatLng: "37.33, -121.89", aroundRadius: 50000 }</code> as search parameters to restrict the result set to 50KM around San Jose.
949
+ ### Geo-Search
829
950
 
830
- Typeahead UI
831
- -------------
832
-
833
- Require ```algolia/v3/algoliasearch.min``` (see [algoliasearch-client-js](https://github.com/algolia/algoliasearch-client-js)) and ```algolia/typeahead.jquery.js``` somewhere in your JavaScript manifest, for example in ```application.js``` if you are using Rails 3.1+:
834
-
835
- ```javascript
836
- //= require algolia/v3/algoliasearch.min
837
- //= require algolia/typeahead.jquery
838
- ```
951
+ Use the <code>geoloc</code> method to localize your record:
839
952
 
840
- We recommend the usage of [hogan](http://twitter.github.io/hogan.js/), a JavaScript templating engine from Twitter.
953
+ ```ruby
954
+ class Contact < ActiveRecord::Base
955
+ include AlgoliaSearch
841
956
 
842
- ```javascript
843
- //= require hogan
957
+ algoliasearch do
958
+ geoloc :lat_attr, :lng_attr
959
+ end
960
+ end
844
961
  ```
845
962
 
846
- Turns any ```input[type="text"]``` element into a typeahead, for example:
847
-
848
- ```javascript
849
- <input name="email" placeholder="test@example.org" id="user_email" />
850
-
851
- <script type="text/javascript">
852
- $(document).ready(function() {
853
- var client = algoliasearch('YourApplicationID', 'SearchOnlyApplicationKey');
854
- var template = Hogan.compile('{{{_highlightResult.email.value}}} ({{{_highlightResult.first_name.value}}} {{{_highlightResult.last_name.value}}})');
855
- $('input#user_email').typeahead(null, {
856
- source: client.initIndex('<%= Contact.index_name %>').ttAdapter(),
857
- displayKey: 'email',
858
- templates: {
859
- suggestion: function(hit) {
860
- return template.render(hit);
861
- }
862
- }
863
- });
864
- });
865
- </script>
866
- ```
963
+ At query time, specify <code>{ aroundLatLng: "37.33, -121.89", aroundRadius: 50000 }</code> as search parameters to restrict the result set to 50KM around San Jose.
867
964
 
868
- Caveats
869
- --------
965
+ ### Caveats
870
966
 
871
967
  This gem makes intensive use of Rails' callbacks to trigger the indexing tasks. If you're using methods bypassing ```after_validation```, ```before_save``` or ```after_commit``` callbacks, it will not index your changes. For example: ```update_attribute``` doesn't perform validations checks, to perform validations when updating use ```update_attributes```.
872
968
 
873
- Timeouts
874
- ---------
969
+ ### Timeouts
875
970
 
876
971
  You can configure a bunch of timeout threshold by setting the following options at initialization time:
877
972
 
@@ -887,8 +982,7 @@ AlgoliaSearch.configuration = {
887
982
  }
888
983
  ```
889
984
 
890
- Note on testing
891
- -----------------
985
+ ### Note on testing
892
986
 
893
987
  To run the specs, please set the <code>ALGOLIA_APPLICATION_ID</code> and <code>ALGOLIA_API_KEY</code> environment variables. Since the tests are creating and removing indexes, DO NOT use your production account.
894
988