algolia 2.0.0.pre.alpha.4 → 2.0.1
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +1 -1
- data/README.md +18 -10
- data/SECURITY.md +3 -0
- data/algolia.gemspec +6 -6
- data/lib/algolia.rb +1 -1
- data/lib/algolia/analytics_client.rb +1 -1
- data/lib/algolia/config/analytics_config.rb +2 -2
- data/lib/algolia/config/base_config.rb +43 -0
- data/lib/algolia/config/insights_config.rb +2 -2
- data/lib/algolia/config/recommendation_config.rb +2 -2
- data/lib/algolia/config/search_config.rb +2 -2
- data/lib/algolia/defaults.rb +2 -2
- data/lib/algolia/error.rb +1 -2
- data/lib/algolia/helpers.rb +5 -3
- data/lib/algolia/insights_client.rb +1 -1
- data/lib/algolia/iterators/object_iterator.rb +5 -4
- data/lib/algolia/iterators/paginator_iterator.rb +5 -3
- data/lib/algolia/recommendation_client.rb +1 -1
- data/lib/algolia/search_client.rb +1 -1
- data/lib/algolia/search_index.rb +37 -37
- data/lib/algolia/transport/request_options.rb +1 -1
- data/lib/algolia/transport/transport.rb +2 -5
- data/lib/algolia/version.rb +1 -1
- data/sig/config/algolia_config.rbs +3 -3
- data/sig/config/analytics_config.rbs +1 -1
- data/sig/config/insights_config.rbs +1 -1
- data/sig/config/recommendation_config.rbs +1 -1
- data/sig/config/search_config.rbs +1 -1
- data/test/algolia/integration/analytics_client_test.rb +6 -6
- data/test/algolia/integration/insights_client_test.rb +11 -11
- data/test/algolia/integration/search_client_test.rb +20 -11
- data/test/algolia/unit/algolia_config_test.rb +16 -0
- data/test/algolia/unit/helpers_test.rb +20 -1
- data/test/algolia/unit/retry_strategy_test.rb +3 -3
- data/test/test_helper.rb +1 -1
- data/upgrade_guide.md +30 -22
- metadata +26 -17
- data/lib/algolia/config/algolia_config.rb +0 -40
| @@ -127,15 +127,12 @@ module Algolia | |
| 127 127 |  | 
| 128 128 | 
             
                  # Generates headers from config headers and optional parameters
         | 
| 129 129 | 
             
                  #
         | 
| 130 | 
            -
                  # @ | 
| 130 | 
            +
                  # @param request_options [RequestOptions]
         | 
| 131 131 | 
             
                  #
         | 
| 132 132 | 
             
                  # @return [Hash] merged headers
         | 
| 133 133 | 
             
                  #
         | 
| 134 134 | 
             
                  def generate_headers(request_options = {})
         | 
| 135 | 
            -
                    headers | 
| 136 | 
            -
                    extra_headers                                               = request_options.headers || {}
         | 
| 137 | 
            -
                    @config.default_headers.each { |key, val| headers[key.to_s] = val }
         | 
| 138 | 
            -
                    extra_headers.each { |key, val| headers[key.to_s]           = val }
         | 
| 135 | 
            +
                    headers = @config.headers.merge(request_options.headers)
         | 
| 139 136 | 
             
                    if request_options.compression_type == Defaults::GZIP_ENCODING
         | 
| 140 137 | 
             
                      headers['Accept-Encoding']  = Defaults::GZIP_ENCODING
         | 
| 141 138 | 
             
                    end
         | 
    
        data/lib/algolia/version.rb
    CHANGED
    
    
| @@ -1,11 +1,10 @@ | |
| 1 1 | 
             
            module Algolia
         | 
| 2 | 
            -
               | 
| 3 | 
            -
              class AlgoliaConfig
         | 
| 2 | 
            +
              class BaseConfig
         | 
| 4 3 | 
             
                attr_accessor app_id: String
         | 
| 5 4 |  | 
| 6 5 | 
             
                attr_accessor api_key: String
         | 
| 7 6 |  | 
| 8 | 
            -
                attr_accessor  | 
| 7 | 
            +
                attr_accessor headers: Hash[String, String]
         | 
| 9 8 |  | 
| 10 9 | 
             
                attr_accessor batch_size: Integer
         | 
| 11 10 |  | 
| @@ -20,5 +19,6 @@ module Algolia | |
| 20 19 | 
             
                attr_accessor symbolize_keys: bool
         | 
| 21 20 |  | 
| 22 21 | 
             
                def initialize: (?::Hash[Symbol, String|[String]] opts) -> void
         | 
| 22 | 
            +
                def set_extra_header: (Symbol|String key, String value) -> void
         | 
| 23 23 | 
             
              end
         | 
| 24 24 | 
             
            end
         | 
| @@ -11,14 +11,14 @@ class AnalyticsClientTest < BaseTest | |
| 11 11 | 
             
                  index1.save_object!({ objectID: 'one' })
         | 
| 12 12 | 
             
                  index2.save_object!({ objectID: 'one' })
         | 
| 13 13 |  | 
| 14 | 
            -
                  ab_test_name = index1. | 
| 14 | 
            +
                  ab_test_name = index1.name
         | 
| 15 15 | 
             
                  tomorrow     = Time.now + 24*60*60
         | 
| 16 16 |  | 
| 17 17 | 
             
                  ab_test = {
         | 
| 18 18 | 
             
                    name: ab_test_name,
         | 
| 19 19 | 
             
                    variants: [
         | 
| 20 | 
            -
                      { index: index1. | 
| 21 | 
            -
                      { index: index2. | 
| 20 | 
            +
                      { index: index1.name, trafficPercentage: 60, description: 'a description' },
         | 
| 21 | 
            +
                      { index: index2.name, trafficPercentage: 40 }
         | 
| 22 22 | 
             
                    ],
         | 
| 23 23 | 
             
                    endAt: tomorrow.strftime('%Y-%m-%dT%H:%M:%SZ')
         | 
| 24 24 | 
             
                  }
         | 
| @@ -74,14 +74,14 @@ class AnalyticsClientTest < BaseTest | |
| 74 74 |  | 
| 75 75 | 
             
                  index.save_object!({ objectID: 'one' })
         | 
| 76 76 |  | 
| 77 | 
            -
                  ab_test_name = index. | 
| 77 | 
            +
                  ab_test_name = index.name
         | 
| 78 78 | 
             
                  tomorrow     = Time.now + 24*60*60
         | 
| 79 79 |  | 
| 80 80 | 
             
                  ab_test = {
         | 
| 81 81 | 
             
                    name: ab_test_name,
         | 
| 82 82 | 
             
                    variants: [
         | 
| 83 | 
            -
                      { index: index. | 
| 84 | 
            -
                      { index: index. | 
| 83 | 
            +
                      { index: index.name, trafficPercentage: 90 },
         | 
| 84 | 
            +
                      { index: index.name, trafficPercentage: 10, customSearchParameters: { ignorePlurals: true } }
         | 
| 85 85 | 
             
                    ],
         | 
| 86 86 | 
             
                    endAt: tomorrow.strftime('%Y-%m-%dT%H:%M:%SZ')
         | 
| 87 87 | 
             
                  }
         | 
| @@ -17,7 +17,7 @@ class InsightsClientTest < BaseTest | |
| 17 17 | 
             
                  client.send_event({
         | 
| 18 18 | 
             
                    eventType: 'click',
         | 
| 19 19 | 
             
                    eventName: 'foo',
         | 
| 20 | 
            -
                    index: index. | 
| 20 | 
            +
                    index: index.name,
         | 
| 21 21 | 
             
                    userToken: 'bar',
         | 
| 22 22 | 
             
                    objectIDs: %w(one two),
         | 
| 23 23 | 
             
                    timestamp: (today - 2).strftime('%Q').to_i
         | 
| @@ -27,14 +27,14 @@ class InsightsClientTest < BaseTest | |
| 27 27 | 
             
                    {
         | 
| 28 28 | 
             
                      eventType: 'click',
         | 
| 29 29 | 
             
                      eventName: 'foo',
         | 
| 30 | 
            -
                      index: index. | 
| 30 | 
            +
                      index: index.name,
         | 
| 31 31 | 
             
                      userToken: 'bar',
         | 
| 32 32 | 
             
                      objectIDs: %w(one two),
         | 
| 33 33 | 
             
                      timestamp: (today - 2).strftime('%Q').to_i
         | 
| 34 34 | 
             
                    }, {
         | 
| 35 35 | 
             
                      eventType: 'click',
         | 
| 36 36 | 
             
                      eventName: 'foo',
         | 
| 37 | 
            -
                      index: index. | 
| 37 | 
            +
                      index: index.name,
         | 
| 38 38 | 
             
                      userToken: 'bar',
         | 
| 39 39 | 
             
                      objectIDs: %w(one two),
         | 
| 40 40 | 
             
                      timestamp: (today - 2).strftime('%Q').to_i
         | 
| @@ -42,37 +42,37 @@ class InsightsClientTest < BaseTest | |
| 42 42 | 
             
                  ])
         | 
| 43 43 |  | 
| 44 44 | 
             
                  user_client = client.user('bar')
         | 
| 45 | 
            -
                  response    = user_client.clicked_object_ids('foo', index. | 
| 45 | 
            +
                  response    = user_client.clicked_object_ids('foo', index.name, %w(one two))
         | 
| 46 46 | 
             
                  assert_equal 200, response[:status]
         | 
| 47 47 | 
             
                  assert_equal 'OK', response[:message]
         | 
| 48 48 |  | 
| 49 49 | 
             
                  query_id = index.search('', { clickAnalytics: true })[:queryID]
         | 
| 50 50 |  | 
| 51 | 
            -
                  response = user_client.clicked_object_ids_after_search('foo', index. | 
| 51 | 
            +
                  response = user_client.clicked_object_ids_after_search('foo', index.name, %w(one two), [1, 2], query_id)
         | 
| 52 52 | 
             
                  assert_equal 200, response[:status]
         | 
| 53 53 | 
             
                  assert_equal 'OK', response[:message]
         | 
| 54 54 |  | 
| 55 | 
            -
                  response = user_client.clicked_filters('foo', index. | 
| 55 | 
            +
                  response = user_client.clicked_filters('foo', index.name, %w(filter:foo filter:bar))
         | 
| 56 56 | 
             
                  assert_equal 200, response[:status]
         | 
| 57 57 | 
             
                  assert_equal 'OK', response[:message]
         | 
| 58 58 |  | 
| 59 | 
            -
                  response = user_client.converted_object_ids('foo', index. | 
| 59 | 
            +
                  response = user_client.converted_object_ids('foo', index.name, %w(one two))
         | 
| 60 60 | 
             
                  assert_equal 200, response[:status]
         | 
| 61 61 | 
             
                  assert_equal 'OK', response[:message]
         | 
| 62 62 |  | 
| 63 | 
            -
                  response = user_client.converted_object_ids_after_search('foo', index. | 
| 63 | 
            +
                  response = user_client.converted_object_ids_after_search('foo', index.name, %w(one two), query_id)
         | 
| 64 64 | 
             
                  assert_equal 200, response[:status]
         | 
| 65 65 | 
             
                  assert_equal 'OK', response[:message]
         | 
| 66 66 |  | 
| 67 | 
            -
                  response = user_client.converted_filters('foo', index. | 
| 67 | 
            +
                  response = user_client.converted_filters('foo', index.name, %w(filter:foo filter:bar))
         | 
| 68 68 | 
             
                  assert_equal 200, response[:status]
         | 
| 69 69 | 
             
                  assert_equal 'OK', response[:message]
         | 
| 70 70 |  | 
| 71 | 
            -
                  response = user_client.viewed_object_ids('foo', index. | 
| 71 | 
            +
                  response = user_client.viewed_object_ids('foo', index.name, %w(one two))
         | 
| 72 72 | 
             
                  assert_equal 200, response[:status]
         | 
| 73 73 | 
             
                  assert_equal 'OK', response[:message]
         | 
| 74 74 |  | 
| 75 | 
            -
                  response = user_client.viewed_filters('foo', index. | 
| 75 | 
            +
                  response = user_client.viewed_filters('foo', index.name, %w(filter:foo filter:bar))
         | 
| 76 76 | 
             
                  assert_equal 200, response[:status]
         | 
| 77 77 | 
             
                  assert_equal 'OK', response[:message]
         | 
| 78 78 | 
             
                end
         | 
| @@ -80,10 +80,10 @@ class SearchClientTest < BaseTest | |
| 80 80 | 
             
                  copy_rules_index     = @@search_client.init_index(get_test_index_name('copy_index_rules'))
         | 
| 81 81 | 
             
                  copy_synonyms_index  = @@search_client.init_index(get_test_index_name('copy_index_synonyms'))
         | 
| 82 82 | 
             
                  copy_full_copy_index = @@search_client.init_index(get_test_index_name('copy_index_full_copy'))
         | 
| 83 | 
            -
                  @@search_client.copy_settings!(@index_name, copy_settings_index. | 
| 84 | 
            -
                  @@search_client.copy_rules!(@index_name, copy_rules_index. | 
| 85 | 
            -
                  @@search_client.copy_synonyms!(@index_name, copy_synonyms_index. | 
| 86 | 
            -
                  @@search_client.copy_index!(@index_name, copy_full_copy_index. | 
| 83 | 
            +
                  @@search_client.copy_settings!(@index_name, copy_settings_index.name)
         | 
| 84 | 
            +
                  @@search_client.copy_rules!(@index_name, copy_rules_index.name)
         | 
| 85 | 
            +
                  @@search_client.copy_synonyms!(@index_name, copy_synonyms_index.name)
         | 
| 86 | 
            +
                  @@search_client.copy_index!(@index_name, copy_full_copy_index.name)
         | 
| 87 87 |  | 
| 88 88 | 
             
                  assert_equal @index.get_settings, copy_settings_index.get_settings
         | 
| 89 89 | 
             
                  assert_equal @index.get_rule(rule[:objectID]), copy_rules_index.get_rule(rule[:objectID])
         | 
| @@ -93,7 +93,7 @@ class SearchClientTest < BaseTest | |
| 93 93 | 
             
                  assert_equal @index.get_synonym(synonym[:objectID]), copy_full_copy_index.get_synonym(synonym[:objectID])
         | 
| 94 94 |  | 
| 95 95 | 
             
                  moved_index = @@search_client.init_index(get_test_index_name('move_index'))
         | 
| 96 | 
            -
                  @@search_client.move_index!(@index_name, moved_index. | 
| 96 | 
            +
                  @@search_client.move_index!(@index_name, moved_index.name)
         | 
| 97 97 |  | 
| 98 98 | 
             
                  moved_index.get_synonym('google_placeholder')
         | 
| 99 99 | 
             
                  moved_index.get_rule('company_auto_faceting')
         | 
| @@ -233,7 +233,16 @@ class SearchClientTest < BaseTest | |
| 233 233 |  | 
| 234 234 | 
             
                  assert_equal 'Key does not exist', exception.message
         | 
| 235 235 |  | 
| 236 | 
            -
                   | 
| 236 | 
            +
                  loop do
         | 
| 237 | 
            +
                    begin
         | 
| 238 | 
            +
                      @@search_client.restore_api_key!(@api_key[:value])
         | 
| 239 | 
            +
                      break
         | 
| 240 | 
            +
                    rescue Algolia::AlgoliaHttpError => e
         | 
| 241 | 
            +
                      if e.code != 404
         | 
| 242 | 
            +
                        raise StandardError
         | 
| 243 | 
            +
                      end
         | 
| 244 | 
            +
                    end
         | 
| 245 | 
            +
                  end
         | 
| 237 246 |  | 
| 238 247 | 
             
                  restored_key = @@search_client.get_api_key(@api_key[:value])
         | 
| 239 248 |  | 
| @@ -261,8 +270,8 @@ class SearchClientTest < BaseTest | |
| 261 270 | 
             
                end
         | 
| 262 271 |  | 
| 263 272 | 
             
                def test_multiple_operations
         | 
| 264 | 
            -
                  index_name1 = @index1. | 
| 265 | 
            -
                  index_name2 = @index2. | 
| 273 | 
            +
                  index_name1 = @index1.name
         | 
| 274 | 
            +
                  index_name2 = @index2.name
         | 
| 266 275 |  | 
| 267 276 | 
             
                  response = @@search_client.multiple_batch!([
         | 
| 268 277 | 
             
                    { indexName: index_name1, action: 'addObject', body: { firstname: 'Jimmie' } },
         | 
| @@ -317,12 +326,12 @@ class SearchClientTest < BaseTest | |
| 317 326 | 
             
                    now             = Time.now.to_i
         | 
| 318 327 | 
             
                    secured_api_key = Algolia::Search::Client.generate_secured_api_key(SEARCH_KEY_1, {
         | 
| 319 328 | 
             
                      validUntil: now + (10 * 60),
         | 
| 320 | 
            -
                      restrictIndices: @index1. | 
| 329 | 
            +
                      restrictIndices: @index1.name
         | 
| 321 330 | 
             
                    })
         | 
| 322 331 |  | 
| 323 332 | 
             
                    secured_client = Algolia::Search::Client.create(APPLICATION_ID_1, secured_api_key)
         | 
| 324 | 
            -
                    secured_index1 = secured_client.init_index(@index1. | 
| 325 | 
            -
                    secured_index2 = secured_client.init_index(@index2. | 
| 333 | 
            +
                    secured_index1 = secured_client.init_index(@index1.name)
         | 
| 334 | 
            +
                    secured_index2 = secured_client.init_index(@index2.name)
         | 
| 326 335 |  | 
| 327 336 | 
             
                    secured_index1.search('')
         | 
| 328 337 | 
             
                    exception = assert_raises Algolia::AlgoliaHttpError do
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            require 'algolia'
         | 
| 2 | 
            +
            require 'test_helper'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class AlgoliaConfigTest
         | 
| 5 | 
            +
              describe 'set an extra header' do
         | 
| 6 | 
            +
                def before_all
         | 
| 7 | 
            +
                  @config = Algolia::BaseConfig.new(application_id: 'app_id', api_key: 'api_key')
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def test_set_extra_header
         | 
| 11 | 
            +
                  @config.set_extra_header('foo', 'bar')
         | 
| 12 | 
            +
                  assert @config.headers['foo']
         | 
| 13 | 
            +
                  assert_equal @config.headers['foo'], 'bar'
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
| @@ -18,7 +18,26 @@ class HelpersTest | |
| 18 18 | 
             
                    replicas: %w(index1 index2)
         | 
| 19 19 | 
             
                  }
         | 
| 20 20 |  | 
| 21 | 
            -
                  deserialized_settings = deserialize_settings(old_settings)
         | 
| 21 | 
            +
                  deserialized_settings = deserialize_settings(old_settings, true)
         | 
| 22 | 
            +
                  assert_equal new_settings, deserialized_settings
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def test_deserialize_settings_with_string
         | 
| 26 | 
            +
                  old_settings = {
         | 
| 27 | 
            +
                    'attributesToIndex' => %w(attr1 attr2),
         | 
| 28 | 
            +
                    'numericAttributesToIndex' => %w(attr1 attr2),
         | 
| 29 | 
            +
                    'slaves' => %w(index1 index2),
         | 
| 30 | 
            +
                    'minWordSizefor1Typo' => 1
         | 
| 31 | 
            +
                  }
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  new_settings = {
         | 
| 34 | 
            +
                    'searchableAttributes' => %w(attr1 attr2),
         | 
| 35 | 
            +
                    'numericAttributesForFiltering' => %w(attr1 attr2),
         | 
| 36 | 
            +
                    'replicas' => %w(index1 index2),
         | 
| 37 | 
            +
                    'minWordSizefor1Typo' => 1
         | 
| 38 | 
            +
                  }
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  deserialized_settings = deserialize_settings(old_settings, false)
         | 
| 22 41 | 
             
                  assert_equal new_settings, deserialized_settings
         | 
| 23 42 | 
             
                end
         | 
| 24 43 | 
             
              end
         | 
| @@ -13,7 +13,7 @@ class RetryStrategyTest | |
| 13 13 | 
             
                  stateful_hosts << "#{@app_id}-4.algolianet.com"
         | 
| 14 14 | 
             
                  stateful_hosts << "#{@app_id}-5.algolianet.com"
         | 
| 15 15 | 
             
                  stateful_hosts << "#{@app_id}-6.algolianet.com"
         | 
| 16 | 
            -
                  @config        = Algolia::Search::Config.new( | 
| 16 | 
            +
                  @config        = Algolia::Search::Config.new(application_id: @app_id, api_key: @api_key, custom_hosts: stateful_hosts)
         | 
| 17 17 | 
             
                end
         | 
| 18 18 |  | 
| 19 19 | 
             
                def test_resets_expired_hosts_according_to_read_type
         | 
| @@ -74,7 +74,7 @@ class RetryStrategyTest | |
| 74 74 | 
             
              describe 'All hosts are unreachable' do
         | 
| 75 75 | 
             
                def test_failure_when_all_hosts_are_down
         | 
| 76 76 | 
             
                  stateful_hosts = ['0.0.0.0']
         | 
| 77 | 
            -
                  @config        = Algolia::Search::Config.new( | 
| 77 | 
            +
                  @config        = Algolia::Search::Config.new(application_id: 'foo', api_key: 'bar', custom_hosts: stateful_hosts)
         | 
| 78 78 | 
             
                  client         = Algolia::Search::Client.create_with_config(@config)
         | 
| 79 79 | 
             
                  index          = client.init_index(get_test_index_name('failure'))
         | 
| 80 80 |  | 
| @@ -91,7 +91,7 @@ class RetryStrategyTest | |
| 91 91 | 
             
                  super
         | 
| 92 92 | 
             
                  @app_id         = 'app_id'
         | 
| 93 93 | 
             
                  @api_key        = 'api_key'
         | 
| 94 | 
            -
                  @config         = Algolia::Search::Config.new( | 
| 94 | 
            +
                  @config         = Algolia::Search::Config.new(application_id: @app_id, api_key: @api_key)
         | 
| 95 95 | 
             
                  @retry_strategy = Algolia::Transport::RetryStrategy.new(@config)
         | 
| 96 96 | 
             
                  @hosts          = @retry_strategy.get_tryable_hosts(READ|WRITE)
         | 
| 97 97 | 
             
                end
         | 
    
        data/test/test_helper.rb
    CHANGED
    
    | @@ -24,7 +24,7 @@ class Minitest::Test | |
| 24 24 |  | 
| 25 25 | 
             
              include Minitest::Hooks
         | 
| 26 26 | 
             
              include Helpers
         | 
| 27 | 
            -
              @@search_config = Algolia::Search::Config.new( | 
| 27 | 
            +
              @@search_config = Algolia::Search::Config.new(application_id: APPLICATION_ID_1, api_key: ADMIN_KEY_1, user_agent: USER_AGENT)
         | 
| 28 28 | 
             
              @@search_client = Algolia::Search::Client.new(@@search_config)
         | 
| 29 29 | 
             
            end
         | 
| 30 30 |  | 
    
        data/upgrade_guide.md
    CHANGED
    
    | @@ -5,7 +5,7 @@ First, you'll have to include the new version in your Gemfile. To do so, change | |
| 5 5 |  | 
| 6 6 | 
             
            ```diff
         | 
| 7 7 | 
             
            - gem 'algoliasearch'
         | 
| 8 | 
            -
            + gem 'algolia', git: 'https://github.com/algolia/algoliasearch-client-ruby.git', tag: 'v2.0.0- | 
| 8 | 
            +
            + gem 'algolia', git: 'https://github.com/algolia/algoliasearch-client-ruby.git', tag: 'v2.0.0-beta.1'
         | 
| 9 9 | 
             
            ```
         | 
| 10 10 |  | 
| 11 11 | 
             
            Then, you'll need to change your current `require` statements:
         | 
| @@ -38,11 +38,17 @@ index = client.init_index('index_name') | |
| 38 38 | 
             
            client = Algolia::Search::Client.create('APP_ID', 'API_KEY')
         | 
| 39 39 | 
             
            index = client.init_index('index_name')
         | 
| 40 40 | 
             
            # or
         | 
| 41 | 
            -
            search_config = Algolia::Search::Config.new( | 
| 41 | 
            +
            search_config = Algolia::Search::Config.new(application_id: app_id, api_key: api_key)
         | 
| 42 42 | 
             
            client = Algolia::Search::Client.create_with_config(search_config)
         | 
| 43 43 | 
             
            index = client.init_index('index_name')
         | 
| 44 44 | 
             
            ```
         | 
| 45 45 |  | 
| 46 | 
            +
            By default the keys of the response hashes are symbols. If you wish to change that for strings, use the following configuration
         | 
| 47 | 
            +
            ```ruby
         | 
| 48 | 
            +
            search_config = Algolia::Search::Config.new(application_id: app_id, api_key: api_key, symbolize_keys: false)
         | 
| 49 | 
            +
            client = Algolia::Search::Client.create_with_config(search_config)
         | 
| 50 | 
            +
            ```
         | 
| 51 | 
            +
             | 
| 46 52 | 
             
            ## Search parameters and request options
         | 
| 47 53 | 
             
            The search parameters and request options are still optional, but they are combined into a single hash instead of two. 
         | 
| 48 54 | 
             
            For example:
         | 
| @@ -55,12 +61,8 @@ index.search('query', search_params, request_opts) | |
| 55 61 |  | 
| 56 62 | 
             
            # After
         | 
| 57 63 | 
             
            opts = {
         | 
| 58 | 
            -
              : | 
| 59 | 
            -
             | 
| 60 | 
            -
              },
         | 
| 61 | 
            -
              :params => {
         | 
| 62 | 
            -
                hitsPerPage: 50
         | 
| 63 | 
            -
              }
         | 
| 64 | 
            +
              headers: { 'X-Algolia-UserToken': 'user123' },
         | 
| 65 | 
            +
              hitsPerPage: 50
         | 
| 64 66 | 
             
            }
         | 
| 65 67 | 
             
            index.search('query', opts)
         | 
| 66 68 | 
             
            ```
         | 
| @@ -69,6 +71,20 @@ index.search('query', opts) | |
| 69 71 |  | 
| 70 72 | 
             
            ### `Client`
         | 
| 71 73 |  | 
| 74 | 
            +
            #### `set_extra_header`
         | 
| 75 | 
            +
            The `set_extra_header` method has been moved from the Client to the `Algolia::BaseConfig` class. You have to define your extra headers on Client instantiation.
         | 
| 76 | 
            +
            ```ruby
         | 
| 77 | 
            +
            # Before
         | 
| 78 | 
            +
            client.set_extra_header('admin', 'admin-key')
         | 
| 79 | 
            +
             | 
| 80 | 
            +
            # After
         | 
| 81 | 
            +
            # `Algolia::Search::Config` inherits from `Algolia::BaseConfig` 
         | 
| 82 | 
            +
            config = Algolia::Search::Config.new(app_id: 'APP_ID', api_key: 'API_KEY')
         | 
| 83 | 
            +
            config.set_extra_header('admin', 'admin-key')
         | 
| 84 | 
            +
             | 
| 85 | 
            +
            client = Algolia::Search::Client.create_with_config(config)
         | 
| 86 | 
            +
            ```
         | 
| 87 | 
            +
             | 
| 72 88 | 
             
            #### `multiple_queries`
         | 
| 73 89 | 
             
            The `strategy` parameter is no longer a string, but a key in the `requestOptions`.
         | 
| 74 90 | 
             
            ```ruby
         | 
| @@ -213,7 +229,7 @@ client.search_user_ids('query', {clusterName: 'my-cluster', hitPerPage: 12, page | |
| 213 229 | 
             
            #### `pending_mappings`
         | 
| 214 230 | 
             
            New method to check the status of your clusters' migration or user creation.
         | 
| 215 231 | 
             
            ```ruby
         | 
| 216 | 
            -
            client. | 
| 232 | 
            +
            client.pending_mappings?({ retrieveMappings: true })
         | 
| 217 233 | 
             
            ``` 
         | 
| 218 234 |  | 
| 219 235 | 
             
            #### `get_logs`
         | 
| @@ -244,12 +260,8 @@ index.search('query', search_params, request_opts) | |
| 244 260 |  | 
| 245 261 | 
             
            # After
         | 
| 246 262 | 
             
            opts = {
         | 
| 247 | 
            -
              : | 
| 248 | 
            -
             | 
| 249 | 
            -
              },
         | 
| 250 | 
            -
              :params => {
         | 
| 251 | 
            -
                hitsPerPage: 50
         | 
| 252 | 
            -
              }
         | 
| 263 | 
            +
              headers: { 'X-Algolia-UserToken': 'user123' },
         | 
| 264 | 
            +
              hitsPerPage: 50
         | 
| 253 265 | 
             
            }
         | 
| 254 266 | 
             
            index.search('query', opts)
         | 
| 255 267 | 
             
            ```
         | 
| @@ -265,12 +277,8 @@ index.search_for_facet_values('category', 'phone', search_params, request_opts) | |
| 265 277 |  | 
| 266 278 | 
             
            # After
         | 
| 267 279 | 
             
            opts = {
         | 
| 268 | 
            -
              : | 
| 269 | 
            -
             | 
| 270 | 
            -
              },
         | 
| 271 | 
            -
              :params => {
         | 
| 272 | 
            -
                hitsPerPage: 50
         | 
| 273 | 
            -
              }
         | 
| 280 | 
            +
              headers: { 'X-Algolia-UserToken': 'user123' },
         | 
| 281 | 
            +
              hitsPerPage: 50
         | 
| 274 282 | 
             
            }
         | 
| 275 283 | 
             
            index.search_for_facet_values('category', 'phone', opts)
         | 
| 276 284 | 
             
            ```
         | 
| @@ -590,6 +598,6 @@ client = Algolia::Client.new({ | |
| 590 598 | 
             
            })
         | 
| 591 599 |  | 
| 592 600 | 
             
            # After
         | 
| 593 | 
            -
            search_config = Algolia::Search::Config.new( | 
| 601 | 
            +
            search_config = Algolia::Search::Config.new(application_id: 'app_id', api_key: 'api_key', read_timeout: 10, connect_timeout: 2)
         | 
| 594 602 | 
             
            client = Algolia::Search::Client.create_with_config(search_config)
         | 
| 595 603 | 
             
            ```
         |