algoliasearch-rails 1.20.4 → 2.2.2

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/LICENSE CHANGED
@@ -1,7 +1,6 @@
1
- The MIT License (MIT)
1
+ MIT License
2
2
 
3
- Copyright (c) 2013 Algolia
4
- http://www.algolia.com/
3
+ Copyright (c) 2013-Present Algolia
5
4
 
6
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
7
6
  of this software and associated documentation files (the "Software"), to deal
@@ -10,13 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
9
  copies of the Software, and to permit persons to whom the Software is
11
10
  furnished to do so, subject to the following conditions:
12
11
 
13
- The above copyright notice and this permission notice shall be included in
14
- all copies or substantial portions of the Software.
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
15
14
 
16
15
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
16
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
17
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- THE SOFTWARE.
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,36 +1,50 @@
1
- # Algolia Search API Client for Rails
2
-
3
- [Algolia Search](https://www.algolia.com) is a hosted full-text, numerical, and faceted search engine capable of delivering realtime results from the first keystroke.
4
-
5
- [![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)
1
+ <p align="center">
2
+ <a href="https://www.algolia.com">
3
+ <img alt="Algolia for Rails" src="https://raw.githubusercontent.com/algolia/algoliasearch-client-common/master/banners/rails.png"/>
4
+ </a>
5
+ </p>
6
+
7
+ <h4 align="center">The perfect starting point to integrate <a href="https://algolia.com" target="_blank">Algolia</a> within your Rails project</h4>
8
+
9
+ <p align="center">
10
+ <a href="https://circleci.com/gh/algolia/algoliasearch-rails"><img src="https://circleci.com/gh/algolia/algoliasearch-rails.svg?style=shield" alt="CircleCI" /></a>
11
+ <a href="http://badge.fury.io/rb/algoliasearch-rails"><img src="https://badge.fury.io/rb/algoliasearch-rails.svg" alt="Gem Version"/></a>
12
+ <a href="https://codeclimate.com/github/algolia/algoliasearch-rails"><img src="https://codeclimate.com/github/algolia/algoliasearch-rails.svg" alt="Code Climate"/></a>
13
+ <img src="https://img.shields.io/badge/ActiveRecord-yes-blue.svg?style=flat-square" alt="ActiveRecord"/>
14
+ <img src="https://img.shields.io/badge/Mongoid-yes-blue.svg?style=flat-square" alt="Mongoid"/>
15
+ <img src="https://img.shields.io/badge/Sequel-yes-blue.svg?style=flat-square" alt="Sequel"/>
16
+ </p>
17
+
18
+ <p align="center">
19
+ <a href="https://www.algolia.com/doc/framework-integration/rails/getting-started/setup/?language=ruby" target="_blank">Documentation</a> •
20
+ <a href="https://discourse.algolia.com" target="_blank">Community Forum</a> •
21
+ <a href="http://stackoverflow.com/questions/tagged/algolia" target="_blank">Stack Overflow</a> •
22
+ <a href="https://github.com/algolia/algoliasearch-rails/issues" target="_blank">Report a bug</a> •
23
+ <a href="https://www.algolia.com/doc/framework-integration/rails/troubleshooting/faq/" target="_blank">FAQ</a> •
24
+ <a href="https://www.algolia.com/support" target="_blank">Support</a>
25
+ </p>
6
26
 
7
27
 
8
28
  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.
9
- Rails 3.x, 4.x and 5.x are all supported.
10
-
11
- 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/).
29
+ Rails 5.x and 6.x are supported.
12
30
 
31
+ 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/).
13
32
 
14
33
 
15
34
 
16
35
  ## API Documentation
17
36
 
18
- You can find the full reference on [Algolia's website](https://www.algolia.com/doc/api-client/rails/).
19
-
20
-
21
- ## Table of Contents
37
+ You can find the full reference on [Algolia's website](https://www.algolia.com/doc/framework-integration/rails/).
22
38
 
23
39
 
24
40
 
25
41
  1. **[Setup](#setup)**
26
-
27
42
  * [Install](#install)
28
43
  * [Configuration](#configuration)
29
44
  * [Timeouts](#timeouts)
30
45
  * [Notes](#notes)
31
46
 
32
47
  1. **[Usage](#usage)**
33
-
34
48
  * [Index Schema](#index-schema)
35
49
  * [Relevancy](#relevancy)
36
50
  * [Indexing](#indexing)
@@ -44,13 +58,12 @@ You can find the full reference on [Algolia's website](https://www.algolia.com/d
44
58
  * [Geo-Search](#geo-search)
45
59
 
46
60
  1. **[Options](#options)**
47
-
48
61
  * [Auto-indexing &amp; asynchronism](#auto-indexing--asynchronism)
49
62
  * [Custom index name](#custom-index-name)
50
63
  * [Per-environment indices](#per-environment-indices)
51
64
  * [Custom attribute definition](#custom-attribute-definition)
52
65
  * [Nested objects/relations](#nested-objectsrelations)
53
- * [Custom `objectID`](#custom-objectid)
66
+ * [Custom <code>objectID</code>](#custom-objectid)
54
67
  * [Restrict indexing to a subset of your data](#restrict-indexing-to-a-subset-of-your-data)
55
68
  * [Sanitizer](#sanitizer)
56
69
  * [UTF-8 Encoding](#utf-8-encoding)
@@ -58,7 +71,6 @@ You can find the full reference on [Algolia's website](https://www.algolia.com/d
58
71
  * [Configuration example](#configuration-example)
59
72
 
60
73
  1. **[Indices](#indices)**
61
-
62
74
  * [Manual indexing](#manual-indexing)
63
75
  * [Manual removal](#manual-removal)
64
76
  * [Reindexing](#reindexing)
@@ -69,12 +81,10 @@ You can find the full reference on [Algolia's website](https://www.algolia.com/d
69
81
  * [Target multiple indices](#target-multiple-indices)
70
82
 
71
83
  1. **[Testing](#testing)**
72
-
73
84
  * [Notes](#notes)
74
85
 
75
-
76
-
77
-
86
+ 1. **[Troubleshooting](#troubleshooting)**
87
+ * [Frequently asked questions](#frequently-asked-questions)
78
88
 
79
89
 
80
90
 
@@ -153,7 +163,7 @@ class Contact < ActiveRecord::Base
153
163
  include AlgoliaSearch
154
164
 
155
165
  algoliasearch do
156
- attribute :first_name, :last_name, :email
166
+ attributes :first_name, :last_name, :email
157
167
  end
158
168
  end
159
169
  ```
@@ -414,7 +424,7 @@ Product.search_for_facet_values('category', 'phone', {
414
424
  ## Group by
415
425
 
416
426
  More info on distinct for grouping can be found
417
- [here](https://www.algolia.com/doc/guides/ranking/distinct/).
427
+ [here](https://www.algolia.com/doc/guides/managing-results/refine-results/grouping/).
418
428
 
419
429
  ```ruby
420
430
  class Contact < ActiveRecord::Base
@@ -454,7 +464,7 @@ At query time, specify <code>{ aroundLatLng: "37.33, -121.89", aroundRadius: 500
454
464
 
455
465
  ## Auto-indexing & asynchronism
456
466
 
457
- 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).
467
+ 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).
458
468
 
459
469
  You can disable auto-indexing and auto-removing setting the following options:
460
470
 
@@ -507,7 +517,7 @@ class MySidekiqWorker
507
517
  if remove
508
518
  # the record has likely already been removed from your database so we cannot
509
519
  # use ActiveRecord#find to load it
510
- index = Algolia::Index.new("index_name")
520
+ index = AlgoliaSearch.client.init_index("index_name")
511
521
  index.delete_object(id)
512
522
  else
513
523
  # the record should be present
@@ -540,7 +550,7 @@ class MySidekiqWorker
540
550
  if remove
541
551
  # the record has likely already been removed from your database so we cannot
542
552
  # use ActiveRecord#find to load it
543
- index = Algolia::Index.new("index_name")
553
+ index = AlgoliaSearch.client.init_index("index_name")
544
554
  index.delete_object(id)
545
555
  else
546
556
  # the record should be present
@@ -659,6 +669,8 @@ end
659
669
 
660
670
  ## Nested objects/relations
661
671
 
672
+ ### Defining the relationship
673
+
662
674
  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).
663
675
 
664
676
  ```ruby
@@ -684,6 +696,82 @@ class Profile < ActiveRecord::Base
684
696
  end
685
697
  ```
686
698
 
699
+ ### Propagating the change from a nested child
700
+
701
+ #### With ActiveRecord
702
+
703
+ With ActiveRecord, we'll be using `touch` and `after_touch` to achieve this.
704
+
705
+ ```ruby
706
+ # app/models/app.rb
707
+ class App < ApplicationRecord
708
+ include AlgoliaSearch
709
+
710
+ belongs_to :author, class_name: :User
711
+ after_touch :index!
712
+
713
+ algoliasearch do
714
+ attribute :title
715
+ attribute :author do
716
+ author.as_json
717
+ end
718
+ end
719
+ end
720
+
721
+ # app/models/user.rb
722
+ class User < ApplicationRecord
723
+ # If your association uses belongs_to
724
+ # - use `touch: true`
725
+ # - do not define an `after_save` hook
726
+ has_many :apps, foreign_key: :author_id
727
+
728
+ after_save { apps.each(&:touch) }
729
+ end
730
+ ```
731
+
732
+ #### With Sequel
733
+
734
+ With Sequel, you can use the `touch` plugin to propagate the changes:
735
+
736
+ ```ruby
737
+ # app/models/app.rb
738
+ class App < Sequel::Model
739
+ include AlgoliaSearch
740
+
741
+ many_to_one :author, class: :User
742
+
743
+ plugin :timestamps
744
+ plugin :touch
745
+
746
+ algoliasearch do
747
+ attribute :title
748
+ attribute :author do
749
+ author.to_hash
750
+ end
751
+ end
752
+ end
753
+
754
+ # app/models/user.rb
755
+ class User < Sequel::Model
756
+ one_to_many :apps, key: :author_id
757
+
758
+ plugin :timestamps
759
+ # Can't use the associations since it won't trigger the after_save
760
+ plugin :touch
761
+
762
+ # Define the associations that need to be touched here
763
+ # Less performant, but allows for the after_save hook to trigger
764
+ def touch_associations
765
+ apps.map(&:touch)
766
+ end
767
+
768
+ def touch
769
+ super
770
+ touch_associations
771
+ end
772
+ end
773
+ ```
774
+
687
775
  ## Custom `objectID`
688
776
 
689
777
  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).
@@ -1072,27 +1160,12 @@ class User < ActiveRecord::Base
1072
1160
  end
1073
1161
  ```
1074
1162
 
1075
- Or you may want to mock Algolia's API calls. We provide a [WebMock](https://github.com/bblimke/webmock) sample configuration that you can use including `algolia/webmock`:
1076
1163
 
1077
- ```ruby
1078
- require 'algolia/webmock'
1164
+ ## ❓ Troubleshooting
1079
1165
 
1080
- describe 'With a mocked client' do
1166
+ Encountering an issue? Before reaching out to support, we recommend heading to our [FAQ](https://www.algolia.com/doc/api-client/troubleshooting/faq/ruby/) where you will find answers for the most common issues and gotchas with the client.
1081
1167
 
1082
- before(:each) do
1083
- WebMock.enable!
1084
- end
1085
-
1086
- it "shouldn't perform any API calls here" do
1087
- User.create(name: 'My Indexed User') # mocked, no API call performed
1088
- User.search('').should == {} # mocked, no API call performed
1089
- end
1090
-
1091
- after(:each) do
1092
- WebMock.disable!
1093
- end
1094
-
1095
- end
1096
- ```
1168
+ ## Use the Dockerfile
1097
1169
 
1170
+ If you want to contribute to this project without installing all its dependencies, you can use our Docker image. Please check our [dedicated guide](DOCKER_README.MD) to learn more.
1098
1171
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  require File.join(File.dirname(__FILE__), 'lib', 'algoliasearch', 'version')
4
4
 
5
+ require 'date'
6
+
5
7
  Gem::Specification.new do |s|
6
8
  s.name = "algoliasearch-rails"
7
9
  s.version = AlgoliaSearch::VERSION
@@ -12,15 +14,14 @@ Gem::Specification.new do |s|
12
14
  s.description = "AlgoliaSearch integration to your favorite ORM"
13
15
  s.email = "contact@algolia.com"
14
16
  s.extra_rdoc_files = [
15
- "ChangeLog",
17
+ "CHANGELOG.MD",
16
18
  "LICENSE",
17
19
  "README.md"
18
20
  ]
19
21
  s.files = [
20
22
  ".document",
21
23
  ".rspec",
22
- ".travis.yml",
23
- "ChangeLog",
24
+ "CHANGELOG.MD",
24
25
  "Gemfile",
25
26
  "Gemfile.lock",
26
27
  "LICENSE",
@@ -77,19 +78,18 @@ Gem::Specification.new do |s|
77
78
 
78
79
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
79
80
  s.add_runtime_dependency(%q<json>, [">= 1.5.1"])
80
- s.add_runtime_dependency(%q<algoliasearch>, [">= 1.17.0", "< 2.0.0"])
81
+ s.add_runtime_dependency(%q<algolia>, ["< 3.0.0"])
81
82
  s.add_development_dependency(%q<will_paginate>, [">= 2.3.15"])
82
83
  s.add_development_dependency(%q<kaminari>, [">= 0"])
83
- s.add_development_dependency "travis"
84
84
  s.add_development_dependency "rake"
85
85
  s.add_development_dependency "rdoc"
86
86
  else
87
87
  s.add_dependency(%q<json>, [">= 1.5.1"])
88
- s.add_dependency(%q<algoliasearch>, [">= 1.17.0", "< 2.0.0"])
88
+ s.add_dependency(%q<algolia>, ["< 3.0.0"])
89
89
  end
90
90
  else
91
91
  s.add_dependency(%q<json>, [">= 1.5.1"])
92
- s.add_dependency(%q<algoliasearch>, [">= 1.17.0", "< 2.0.0"])
92
+ s.add_dependency(%q<algolia>, ["< 3.0.0"])
93
93
  end
94
94
  end
95
95
 
@@ -1,12 +1,38 @@
1
1
  module AlgoliaSearch
2
2
  module Configuration
3
+ def initialize
4
+ @client = nil
5
+ end
6
+
3
7
  def configuration
4
8
  @@configuration || raise(NotConfigured, "Please configure AlgoliaSearch. Set AlgoliaSearch.configuration = {application_id: 'YOUR_APPLICATION_ID', api_key: 'YOUR_API_KEY'}")
5
9
  end
6
10
 
7
11
  def configuration=(configuration)
8
- @@configuration = configuration.merge(:user_agent => "Algolia for Rails (#{AlgoliaSearch::VERSION}); Algolia for Ruby (#{Algolia::VERSION})")
9
- Algolia.init @@configuration
12
+ @@configuration = configuration.merge(
13
+ :user_agent => "Algolia for Rails (#{AlgoliaSearch::VERSION}); Rails (#{Rails::VERSION::STRING})",
14
+ :symbolize_keys => false
15
+ )
16
+ end
17
+
18
+ def client_opts
19
+ @@opts ||= {}
20
+ end
21
+
22
+ def client_opts=(opts)
23
+ @@opts = opts
24
+ end
25
+
26
+ def client
27
+ if @client.nil?
28
+ setup_client
29
+ end
30
+
31
+ @client
32
+ end
33
+
34
+ def setup_client
35
+ @client = Algolia::Search::Client.new(Algolia::Search::Config.new(@@configuration), client_opts)
10
36
  end
11
37
  end
12
38
  end
@@ -9,7 +9,7 @@ module AlgoliaSearch
9
9
  class Kaminari < ::Kaminari::PaginatableArray
10
10
 
11
11
  def initialize(array, options)
12
- super(array, options)
12
+ super(array, **options)
13
13
  end
14
14
 
15
15
  def limit(num)
@@ -1,9 +1,14 @@
1
1
  namespace :algoliasearch do
2
-
2
+
3
3
  desc "Reindex all models"
4
4
  task :reindex => :environment do
5
5
  AlgoliaSearch::Utilities.reindex_all_models
6
6
  end
7
+
8
+ desc "Set settings to all indexes"
9
+ task :set_all_settings => :environment do
10
+ AlgoliaSearch::Utilities.set_settings_all_models
11
+ end
7
12
 
8
13
  desc "Clear all indexes"
9
14
  task :clear_indexes => :environment do
@@ -2,7 +2,11 @@ module AlgoliaSearch
2
2
  module Utilities
3
3
  class << self
4
4
  def get_model_classes
5
- Rails.application.eager_load! if Rails.application # Ensure all models are loaded (not necessary in production when cache_classes is true).
5
+ if Rails.application && defined?(Rails.autoloaders) && Rails.autoloaders.zeitwerk_enabled?
6
+ Zeitwerk::Loader.eager_load_all
7
+ elsif Rails.application
8
+ Rails.application.eager_load!
9
+ end
6
10
  AlgoliaSearch.instance_variable_get :@included_in
7
11
  end
8
12
 
@@ -25,6 +29,19 @@ module AlgoliaSearch
25
29
  klass.algolia_reindex
26
30
  end
27
31
  end
32
+
33
+ def set_settings_all_models
34
+ klasses = get_model_classes
35
+
36
+ puts ''
37
+ puts "Pushing settings for #{klasses.count} models: #{klasses.to_sentence}."
38
+ puts ''
39
+
40
+ klasses.each do |klass|
41
+ puts "Pushing #{klass} settings..."
42
+ klass.algolia_set_settings
43
+ end
44
+ end
28
45
  end
29
46
  end
30
47
  end
@@ -1,3 +1,3 @@
1
1
  module AlgoliaSearch
2
- VERSION = '1.20.4'
2
+ VERSION = '2.2.2'
3
3
  end