redi_search 1.0.4 → 3.0.0
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/.github/workflows/lint.yml +18 -0
- data/.github/workflows/tests.yml +45 -0
- data/.rubocop.yml +136 -193
- data/Appraisals +6 -6
- data/Gemfile +4 -4
- data/README.md +79 -92
- data/Rakefile +15 -3
- data/bin/console +29 -0
- data/gemfiles/{rails_51.gemfile → activerecord_51.gemfile} +3 -4
- data/gemfiles/{rails_52.gemfile → activerecord_52.gemfile} +3 -4
- data/gemfiles/{rails_6.gemfile → activerecord_61.gemfile} +3 -4
- data/lib/redi_search.rb +8 -7
- data/lib/redi_search/{alter.rb → add_field.rb} +13 -5
- data/lib/redi_search/client.rb +23 -11
- data/lib/redi_search/client/response.rb +5 -1
- data/lib/redi_search/configuration.rb +1 -11
- data/lib/redi_search/create.rb +7 -4
- data/lib/redi_search/document.rb +5 -13
- data/lib/redi_search/document/display.rb +9 -9
- data/lib/redi_search/document/finder.rb +12 -42
- data/lib/redi_search/hset.rb +28 -0
- data/lib/redi_search/index.rb +24 -22
- data/lib/redi_search/lazily_load.rb +6 -11
- data/lib/redi_search/log_subscriber.rb +25 -53
- data/lib/redi_search/model.rb +37 -39
- data/lib/redi_search/schema.rb +3 -3
- data/lib/redi_search/schema/field.rb +2 -3
- data/lib/redi_search/schema/tag_field.rb +1 -1
- data/lib/redi_search/schema/text_field.rb +1 -1
- data/lib/redi_search/search.rb +15 -25
- data/lib/redi_search/search/clauses.rb +6 -7
- data/lib/redi_search/search/clauses/application_clause.rb +20 -5
- data/lib/redi_search/search/clauses/boolean.rb +9 -9
- data/lib/redi_search/search/clauses/highlight.rb +18 -2
- data/lib/redi_search/search/clauses/limit.rb +7 -5
- data/lib/redi_search/search/clauses/or.rb +1 -1
- data/lib/redi_search/search/clauses/return.rb +1 -1
- data/lib/redi_search/search/clauses/slop.rb +1 -1
- data/lib/redi_search/search/clauses/sort_by.rb +1 -1
- data/lib/redi_search/search/clauses/where.rb +10 -2
- data/lib/redi_search/search/result.rb +10 -10
- data/lib/redi_search/search/term.rb +7 -6
- data/lib/redi_search/spellcheck.rb +3 -4
- data/lib/redi_search/spellcheck/result.rb +1 -1
- data/lib/redi_search/validatable.rb +49 -0
- data/lib/redi_search/validations/inclusion.rb +26 -0
- data/lib/redi_search/validations/numericality.rb +45 -0
- data/lib/redi_search/validations/presence.rb +29 -0
- data/lib/redi_search/version.rb +1 -1
- data/redi_search.gemspec +1 -3
- metadata +20 -50
- data/.travis.yml +0 -31
- data/bin/test +0 -7
- data/lib/redi_search/add.rb +0 -63
    
        data/Appraisals
    CHANGED
    
    | @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            appraise " | 
| 4 | 
            -
              gem " | 
| 3 | 
            +
            appraise "activerecord-52" do
         | 
| 4 | 
            +
              gem "activerecord", "< 6.0", ">= 5.2"
         | 
| 5 5 | 
             
            end
         | 
| 6 6 |  | 
| 7 | 
            -
            appraise " | 
| 8 | 
            -
              gem " | 
| 7 | 
            +
            appraise "activerecord-51" do
         | 
| 8 | 
            +
              gem "activerecord", "< 5.2", ">= 5.1"
         | 
| 9 9 | 
             
            end
         | 
| 10 10 |  | 
| 11 | 
            -
            appraise " | 
| 12 | 
            -
              gem " | 
| 11 | 
            +
            appraise "activerecord-61" do
         | 
| 12 | 
            +
              gem "activerecord", "6.1.0.rc1"
         | 
| 13 13 | 
             
            end
         | 
    
        data/Gemfile
    CHANGED
    
    | @@ -2,18 +2,18 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            source "https://rubygems.org"
         | 
| 4 4 |  | 
| 5 | 
            -
            git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
         | 
| 5 | 
            +
            git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
         | 
| 6 6 |  | 
| 7 7 | 
             
            gemspec
         | 
| 8 8 |  | 
| 9 | 
            +
            gem "appraisal", "~> 2.2"
         | 
| 9 10 | 
             
            gem "faker"
         | 
| 10 11 | 
             
            gem "mocha"
         | 
| 11 12 | 
             
            gem "pry"
         | 
| 12 | 
            -
            gem "pry-rails"
         | 
| 13 13 | 
             
            gem "rubocop"
         | 
| 14 | 
            +
            gem "rubocop-minitest"
         | 
| 14 15 | 
             
            gem "rubocop-performance"
         | 
| 15 | 
            -
            gem "rubocop-rails"
         | 
| 16 16 | 
             
            gem "simplecov"
         | 
| 17 17 | 
             
            gem "sqlite3"
         | 
| 18 18 |  | 
| 19 | 
            -
            gem " | 
| 19 | 
            +
            gem "activerecord", "~> 6.0.0"
         | 
    
        data/README.md
    CHANGED
    
    | @@ -6,8 +6,7 @@ | |
| 6 6 |  | 
| 7 7 | 
             
            # RediSearch
         | 
| 8 8 |  | 
| 9 | 
            -
             | 
| 10 | 
            -
            [](https://codeclimate.com/github/npezza93/redi_search/test_coverage)
         | 
| 9 | 
            +
            
         | 
| 11 10 | 
             
            [](https://codeclimate.com/github/npezza93/redi_search/maintainability)
         | 
| 12 11 |  | 
| 13 12 | 
             
            A simple, but powerful, Ruby wrapper around RediSearch, a search engine on top of
         | 
| @@ -24,11 +23,13 @@ macOS or Linux you can install via Homebrew. | |
| 24 23 |  | 
| 25 24 | 
             
            To install RediSearch check out,
         | 
| 26 25 | 
             
            [https://oss.redislabs.com/redisearch/Quick_Start.html](https://oss.redislabs.com/redisearch/Quick_Start.html).
         | 
| 27 | 
            -
            Once you have RediSearch built, you  | 
| 28 | 
            -
            load the  | 
| 29 | 
            -
            the redis.conf file can be found | 
| 26 | 
            +
            Once you have RediSearch built, if you are not using Docker, you can update your
         | 
| 27 | 
            +
            redis.conf file to always load the RediSearch module with
         | 
| 28 | 
            +
            `loadmodule /path/to/redisearch.so`. (On macOS the redis.conf file can be found
         | 
| 29 | 
            +
            at `/usr/local/etc/redis.conf`)
         | 
| 30 30 |  | 
| 31 | 
            -
            After Redis and RediSearch are up and running, add  | 
| 31 | 
            +
            After Redis and RediSearch are up and running, add the following line to your
         | 
| 32 | 
            +
            Gemfile:
         | 
| 32 33 |  | 
| 33 34 | 
             
            ```ruby
         | 
| 34 35 | 
             
            gem 'redi_search'
         | 
| @@ -51,7 +52,7 @@ require 'redi_search' | |
| 51 52 |  | 
| 52 53 | 
             
            Once the gem is installed and required you'll need to configure it with your
         | 
| 53 54 | 
             
            Redis configuration. If you're on Rails, this should go in an initializer
         | 
| 54 | 
            -
            (`config/initializers/redi_search.rb`)
         | 
| 55 | 
            +
            (`config/initializers/redi_search.rb`).
         | 
| 55 56 |  | 
| 56 57 | 
             
            ```ruby
         | 
| 57 58 | 
             
            RediSearch.configure do |config|
         | 
| @@ -74,7 +75,7 @@ end | |
| 74 75 |  | 
| 75 76 | 
             
            ## Preface
         | 
| 76 77 | 
             
            RediSearch revolves around a search index, so lets start with
         | 
| 77 | 
            -
            defining what a search index is. According to [ | 
| 78 | 
            +
            defining what a search index is. According to [Swiftype](https://swiftype.com):
         | 
| 78 79 | 
             
            > A search index is a body of structured data that a search engine refers to
         | 
| 79 80 | 
             
            > when looking for results that are relevant to a specific query. Indexes are a
         | 
| 80 81 | 
             
            > critical piece of any search system, since they must be tailored to the
         | 
| @@ -242,40 +243,35 @@ With no options: `{ place: :geo }` | |
| 242 243 |  | 
| 243 244 | 
             
            ## Document
         | 
| 244 245 |  | 
| 245 | 
            -
            A `Document` is the Ruby representation of a  | 
| 246 | 
            +
            A `Document` is the Ruby representation of a Redis hash.
         | 
| 246 247 |  | 
| 247 | 
            -
            You can fetch a `Document` using `.get`  | 
| 248 | 
            -
            - `get(index, document_id)` fetches a single  | 
| 249 | 
            -
            `document_id`.
         | 
| 250 | 
            -
            - `mget(index, *document_ids)` fetches a collection of `Document`s
         | 
| 251 | 
            -
            in an `Index` for the given `document_ids`.
         | 
| 248 | 
            +
            You can fetch a `Document` using `.get` class methods.
         | 
| 249 | 
            +
            - `get(index, document_id)` fetches a single `Document` in an `Index` for a
         | 
| 250 | 
            +
            given `document_id`.
         | 
| 252 251 |  | 
| 253 252 | 
             
            You can also make a `Document` instance using the
         | 
| 254 253 | 
             
            `.for_object(index, record, serializer: nil, only: [])` class method. It takes
         | 
| 255 | 
            -
            an `Index` instance and a  | 
| 256 | 
            -
            fields specified in the  | 
| 257 | 
            -
            the object and responds to all the fields specified in the  | 
| 258 | 
            -
            `only` accepts an array of fields from the schema and limits the | 
| 259 | 
            -
            passed to the `Document`.
         | 
| 254 | 
            +
            an `Index` instance and a Ruby object. That object must respond to all the
         | 
| 255 | 
            +
            fields specified in the `Index`'s `Schema` or pass a serializer class that
         | 
| 256 | 
            +
            accepts the object and responds to all the fields specified in the `Index`'s
         | 
| 257 | 
            +
            `Schema`. `only` accepts an array of fields from the schema and limits the
         | 
| 258 | 
            +
            fields that are passed to the `Document`.
         | 
| 260 259 |  | 
| 261 260 | 
             
            Once you have an instance of a `Document`, it responds to all the fields
         | 
| 262 | 
            -
            specified in the  | 
| 263 | 
            -
            automatically prepended with the  | 
| 264 | 
            -
            uniqueness. We prepend the  | 
| 265 | 
            -
            same id in different  | 
| 266 | 
            -
            There is also a `#document_id_without_index` method | 
| 267 | 
            -
            index name.
         | 
| 268 | 
            -
             | 
| 269 | 
            -
            Finally there is a `#del` method that will remove the document from the index.
         | 
| 270 | 
            -
            It optionally accepts a `delete_document` named argument that signifies whether
         | 
| 271 | 
            -
            the document should be completely removed from the Redis instance vs just the
         | 
| 272 | 
            -
            index.
         | 
| 261 | 
            +
            specified in the `Index`'s `Schema` as methods and `document_id`. `document_id`
         | 
| 262 | 
            +
            is automatically prepended with the `Index`'s names unless it already is to
         | 
| 263 | 
            +
            ensure uniqueness. We prepend the `Index` name because if you have two
         | 
| 264 | 
            +
            `Document`s with the same id in different `Index`s we don't want the `Document`s
         | 
| 265 | 
            +
            to override each other. There is also a `#document_id_without_index` method
         | 
| 266 | 
            +
            which removes the prepended index name.
         | 
| 273 267 |  | 
| 268 | 
            +
            Finally there is a `#del` method that will remove the `Document` from the
         | 
| 269 | 
            +
            `Index`.
         | 
| 274 270 |  | 
| 275 271 | 
             
            ## Index
         | 
| 276 272 |  | 
| 277 | 
            -
            To initialize an  | 
| 278 | 
            -
             | 
| 273 | 
            +
            To initialize an `Index`, pass the name of the `Index` as a string or symbol
         | 
| 274 | 
            +
            and the `Schema`.
         | 
| 279 275 |  | 
| 280 276 | 
             
            ```ruby
         | 
| 281 277 | 
             
            RediSearch::Index.new(name_of_index, schema)
         | 
| @@ -291,7 +287,7 @@ RediSearch::Index.new(name_of_index, schema) | |
| 291 287 | 
             
                    - For efficiency, RediSearch encodes indexes differently if they are
         | 
| 292 288 | 
             
                      created with less than 32 text fields. This option forces RediSearch
         | 
| 293 289 | 
             
                      to encode indexes as if there were more than 32 text fields, which
         | 
| 294 | 
            -
                      allows you to add additional fields (beyond 32) using ` | 
| 290 | 
            +
                      allows you to add additional fields (beyond 32) using `add_field`.
         | 
| 295 291 | 
             
                  - `no_offsets: #{true || false}`
         | 
| 296 292 | 
             
                    - If set, we do not store term offsets for documents (saves memory, does
         | 
| 297 293 | 
             
                      not allow exact searches or highlighting). Implies `no_highlight`.
         | 
| @@ -312,50 +308,39 @@ RediSearch::Index.new(name_of_index, schema) | |
| 312 308 | 
             
                    - If set, we avoid saving the term frequencies in the index. This saves
         | 
| 313 309 | 
             
                      memory but does not allow sorting based on the frequencies of a given
         | 
| 314 310 | 
             
                      term within the document.
         | 
| 315 | 
            -
            - `drop`
         | 
| 316 | 
            -
              - Drops the  | 
| 311 | 
            +
            - `drop(keep_docs: false)`
         | 
| 312 | 
            +
              - Drops the `Index` from the Redis instance, returns a boolean. Has an
         | 
| 317 313 | 
             
                accompanying bang method that will raise an exception upon failure. Will
         | 
| 318 | 
            -
                return `false` if the  | 
| 314 | 
            +
                return `false` if the `Index` has already been dropped. Takes an option
         | 
| 315 | 
            +
                keyword arg, `keep_docs`, that will by default remove all the document
         | 
| 316 | 
            +
                hashes in Redis.
         | 
| 319 317 | 
             
            - `exist?`
         | 
| 320 | 
            -
              - Returns a boolean signifying  | 
| 318 | 
            +
              - Returns a boolean signifying `Index` existence.
         | 
| 321 319 | 
             
            - `info`
         | 
| 322 | 
            -
              - Returns a struct object with all the information about the  | 
| 320 | 
            +
              - Returns a struct object with all the information about the `Index`.
         | 
| 323 321 | 
             
            - `fields`
         | 
| 324 | 
            -
              - Returns an array of the field names in the  | 
| 325 | 
            -
            - `add(document | 
| 326 | 
            -
              - Takes a `Document` object | 
| 322 | 
            +
              - Returns an array of the field names in the `Index`.
         | 
| 323 | 
            +
            - `add(document)`
         | 
| 324 | 
            +
              - Takes a `Document` object. Has an
         | 
| 327 325 | 
             
                accompanying bang method that will raise an exception upon failure.
         | 
| 328 | 
            -
             | 
| 329 | 
            -
                - `language` -> Use a stemmer for the supplied language during indexing.
         | 
| 330 | 
            -
                - `no_save` -> Don't save the actual document in the database and only index it.
         | 
| 331 | 
            -
                - `replace` -> Accepts a boolean or a hash. If a truthy value is passed, we
         | 
| 332 | 
            -
                  will do an UPSERT style insertion - and delete an older version of the
         | 
| 333 | 
            -
                  document if it exists.
         | 
| 334 | 
            -
                - `replace: { partial: true }` -> Allows you to not have to specify all
         | 
| 335 | 
            -
                  fields for reindexing. Fields not given to the command will be loaded from
         | 
| 336 | 
            -
                  the current version of the document.
         | 
| 337 | 
            -
            - `add_multiple!(documents, score: 1.0, replace: {}, language: nil, no_save: false)`
         | 
| 326 | 
            +
            - `add_multiple(documents)`
         | 
| 338 327 | 
             
              - Takes an array of `Document` objects. This provides a more performant way to
         | 
| 339 | 
            -
                add multiple documents to the  | 
| 340 | 
            -
            - `del(document | 
| 341 | 
            -
              - Removes a  | 
| 342 | 
            -
                document should be completely removed from the Redis instance vs just the
         | 
| 343 | 
            -
                index.
         | 
| 328 | 
            +
                add multiple documents to the `Index`. Accepts the same options as `add`.
         | 
| 329 | 
            +
            - `del(document)`
         | 
| 330 | 
            +
              - Removes a `Document` from the `Index`.
         | 
| 344 331 | 
             
            - `document_count`
         | 
| 345 | 
            -
              - Returns the number of  | 
| 346 | 
            -
            - ` | 
| 347 | 
            -
              - Adds a new field to the  | 
| 348 | 
            -
            - `reindex(documents, recreate: false | 
| 349 | 
            -
               - If `recreate` is `true` the  | 
| 350 | 
            -
               - `options` accepts the same options as `add`
         | 
| 332 | 
            +
              - Returns the number of `Document`s in the `Index`
         | 
| 333 | 
            +
            - `add_field(field_name, schema)`
         | 
| 334 | 
            +
              - Adds a new field to the `Index`. Ex: `index.add_field(:first_name, text: { phonetic: "dm:en" })`
         | 
| 335 | 
            +
            - `reindex(documents, recreate: false)`
         | 
| 336 | 
            +
               - If `recreate` is `true` the `Index` will be dropped and recreated
         | 
| 351 337 |  | 
| 352 338 |  | 
| 353 339 | 
             
            ## Searching
         | 
| 354 340 |  | 
| 355 341 | 
             
            Searching is initiated off a `RediSearch::Index` instance with clauses that can
         | 
| 356 342 | 
             
            be chained together. When searching, an array of `Document`s is returned
         | 
| 357 | 
            -
            which has public reader methods for all the schema fields | 
| 358 | 
            -
            method which returns the id of the document prefixed with the index name.
         | 
| 343 | 
            +
            which has public reader methods for all the schema fields.
         | 
| 359 344 |  | 
| 360 345 | 
             
            ```ruby
         | 
| 361 346 | 
             
            main ❯ index = RediSearch::Index.new("user_idx", name: { text: { phonetic: "dm:en" } })
         | 
| @@ -440,15 +425,15 @@ index.search.where(number: -Float::INFINITY..0) | |
| 440 425 | 
             
              phrase terms. (i.e the slop for exact phrases is 0)
         | 
| 441 426 | 
             
            - `in_order`
         | 
| 442 427 | 
             
              - Usually used in conjunction with `slop`. We make sure the query terms appear
         | 
| 443 | 
            -
                in the same order in the  | 
| 444 | 
            -
                between them.
         | 
| 428 | 
            +
                in the same order in the `Document` as in the query, regardless of the
         | 
| 429 | 
            +
                offsets between them.
         | 
| 445 430 | 
             
            - `no_content`
         | 
| 446 | 
            -
              - Only return the  | 
| 447 | 
            -
                RediSearch is being used on a Rails model where the  | 
| 448 | 
            -
                don't matter and it's being converted into ActiveRecord objects.
         | 
| 431 | 
            +
              - Only return the `Document` ids and not the content. This is useful if
         | 
| 432 | 
            +
                RediSearch is being used on a Rails model where the `Document` attributes
         | 
| 433 | 
            +
                don't matter and it's being converted into `ActiveRecord` objects.
         | 
| 449 434 | 
             
            - `language(language)`
         | 
| 450 435 | 
             
              - Stemmer to use for the supplied language during search for query expansion.
         | 
| 451 | 
            -
                If querying  | 
| 436 | 
            +
                If querying `Document`s in Chinese, this should be set to chinese in order to
         | 
| 452 437 | 
             
                properly tokenize the query terms. If an unsupported language is sent, the
         | 
| 453 438 | 
             
                command returns an error.
         | 
| 454 439 | 
             
            - `sort_by(field, order: :asc)`
         | 
| @@ -459,7 +444,7 @@ index.search.where(number: -Float::INFINITY..0) | |
| 459 444 | 
             
              - Limit the results to the specified `num` at the `offset`. The default limit
         | 
| 460 445 | 
             
                is set to `10`.
         | 
| 461 446 | 
             
            - `count`
         | 
| 462 | 
            -
              - Returns the number of  | 
| 447 | 
            +
              - Returns the number of `Document`s found in the search query
         | 
| 463 448 | 
             
            - `highlight(fields: [], opening_tag: "<b>", closing_tag: "</b>")`
         | 
| 464 449 | 
             
              - Use this option to format occurrences of matched text. `fields` are an
         | 
| 465 450 | 
             
                array of fields to be highlighted.
         | 
| @@ -469,16 +454,14 @@ index.search.where(number: -Float::INFINITY..0) | |
| 469 454 | 
             
            - `no_stop_words`
         | 
| 470 455 | 
             
              - Do not filter stopwords from the query.
         | 
| 471 456 | 
             
            - `with_scores`
         | 
| 472 | 
            -
              - Include the relative internal score of each  | 
| 457 | 
            +
              - Include the relative internal score of each `Document`. This can be used to
         | 
| 473 458 | 
             
                merge results from multiple instances. This will add a `score` method to the
         | 
| 474 459 | 
             
                returned `Document` instances.
         | 
| 475 460 | 
             
            - `return(*fields)`
         | 
| 476 | 
            -
              - Limit which fields from the  | 
| 461 | 
            +
              - Limit which fields from the `Document` are returned.
         | 
| 477 462 | 
             
            - `explain`
         | 
| 478 463 | 
             
              - Returns the execution plan for a complex query. In the returned response,
         | 
| 479 464 | 
             
                a + on a term is an indication of stemming.
         | 
| 480 | 
            -
            - `to_redis`
         | 
| 481 | 
            -
              - Returns the command to be executed without executing it.
         | 
| 482 465 |  | 
| 483 466 |  | 
| 484 467 | 
             
            ## Spellcheck
         | 
| @@ -507,8 +490,8 @@ main ❯ index.spellcheck("jimy", distance: 2).first.suggestions | |
| 507 490 |  | 
| 508 491 | 
             
            ## Rails Integration
         | 
| 509 492 |  | 
| 510 | 
            -
            Integration with Rails is super easy! Call `redi_search` with the schema | 
| 511 | 
            -
             | 
| 493 | 
            +
            Integration with Rails is super easy! Call `redi_search` with the `schema`
         | 
| 494 | 
            +
            keyword argument from inside your model. Ex:
         | 
| 512 495 |  | 
| 513 496 | 
             
            ```ruby
         | 
| 514 497 | 
             
            class User < ApplicationRecord
         | 
| @@ -522,10 +505,9 @@ end | |
| 522 505 | 
             
            This will automatically add `User.search` and `User.spellcheck`
         | 
| 523 506 | 
             
            methods which behave the same as if you called them on an `Index` instance.
         | 
| 524 507 |  | 
| 525 | 
            -
            `User.reindex(only: [] | 
| 526 | 
            -
             | 
| 527 | 
            -
             | 
| 528 | 
            -
              - `Document`s do not to be passed as the first parameter. The `search_import`
         | 
| 508 | 
            +
            `User.reindex(recreate: false, only: [])` is also added and behaves
         | 
| 509 | 
            +
            similarly to `RediSearch::Index#reindex`. Some of the differences include:
         | 
| 510 | 
            +
              - `Document`s do not need to be passed as the first parameter. The `search_import`
         | 
| 529 511 | 
             
                scope is automatically called and all the records are converted
         | 
| 530 512 | 
             
                to `Document`s.
         | 
| 531 513 | 
             
              - Accepts an optional `only` parameter where you can specify a limited number
         | 
| @@ -552,8 +534,8 @@ class UserSerializer < SimpleDelegator | |
| 552 534 | 
             
            end
         | 
| 553 535 | 
             
            ```
         | 
| 554 536 |  | 
| 555 | 
            -
            You can  | 
| 556 | 
            -
            it can be used to limit the records to index.
         | 
| 537 | 
            +
            You can override the `search_import` scope on the model to eager load
         | 
| 538 | 
            +
            relationships when indexing or it can be used to limit the records to index.
         | 
| 557 539 |  | 
| 558 540 | 
             
            ```ruby
         | 
| 559 541 | 
             
            class User < ApplicationRecord
         | 
| @@ -561,7 +543,11 @@ class User < ApplicationRecord | |
| 561 543 | 
             
            end
         | 
| 562 544 | 
             
            ```
         | 
| 563 545 |  | 
| 564 | 
            -
             | 
| 546 | 
            +
            When searching, by default a collection of `Document`s is returned. Calling
         | 
| 547 | 
            +
            `#results` on the search query will execute the search, and then look up all the
         | 
| 548 | 
            +
            found records in the database and return an ActiveRecord relation.
         | 
| 549 | 
            +
             | 
| 550 | 
            +
            The default `Index` name for model `Index`s is
         | 
| 565 551 | 
             
            `#{model_name.plural}_#{RediSearch.env}`. The `redi_search` method takes an
         | 
| 566 552 | 
             
            optional `index_prefix` argument which gets prepended to the index name:
         | 
| 567 553 |  | 
| @@ -578,15 +564,16 @@ User.redi_search_index.name | |
| 578 564 | 
             
            ```
         | 
| 579 565 |  | 
| 580 566 | 
             
            When integrating RediSearch into a model, records will automatically be indexed
         | 
| 581 | 
            -
            after creating and updating and will be removed from the  | 
| 567 | 
            +
            after creating and updating and will be removed from the `Index` upon
         | 
| 568 | 
            +
            destruction.
         | 
| 582 569 |  | 
| 583 | 
            -
            There are few more convenience methods that are publicly available:
         | 
| 570 | 
            +
            There are a few more convenience methods that are publicly available:
         | 
| 584 571 | 
             
            - `redi_search_document`
         | 
| 585 572 | 
             
              - Returns the record as a `RediSearch::Document` instance
         | 
| 586 573 | 
             
            - `redi_search_delete_document`
         | 
| 587 | 
            -
              - Removes the record from the  | 
| 574 | 
            +
              - Removes the record from the `Index`
         | 
| 588 575 | 
             
            - `redi_search_add_document`
         | 
| 589 | 
            -
              - Adds the record to the  | 
| 576 | 
            +
              - Adds the record to the `Index`
         | 
| 590 577 | 
             
            - `redi_search_index`
         | 
| 591 578 | 
             
              - Returns the `RediSearch::Index` instance
         | 
| 592 579 |  | 
| @@ -594,15 +581,15 @@ There are few more convenience methods that are publicly available: | |
| 594 581 | 
             
            ## Development
         | 
| 595 582 |  | 
| 596 583 | 
             
            After checking out the repo, run `bin/setup` to install dependencies. Then, run
         | 
| 597 | 
            -
            `rake test` to run the  | 
| 598 | 
            -
             | 
| 599 | 
            -
             | 
| 584 | 
            +
            `rake test` to run the both unit and integration tests. To run them individually
         | 
| 585 | 
            +
            you can run `rake test:unit` or `rake test:integration`. You can also run
         | 
| 586 | 
            +
            `bin/console` for an interactive prompt that will allow you to experiment.
         | 
| 600 587 |  | 
| 601 588 | 
             
            To install this gem onto your local machine, run `bundle exec rake install`. To
         | 
| 602 589 | 
             
            release a new version, execute `bin/publish (major|minor|patch)` which will
         | 
| 603 590 | 
             
            update the version number in `version.rb`, create a git tag for the version,
         | 
| 604 591 | 
             
            push git commits and tags, and push the `.gem` file to
         | 
| 605 | 
            -
            [rubygems.org](https://rubygems.org).
         | 
| 592 | 
            +
            [rubygems.org](https://rubygems.org) and GitHub.
         | 
| 606 593 |  | 
| 607 594 | 
             
            ## Contributing
         | 
| 608 595 |  | 
    
        data/Rakefile
    CHANGED
    
    | @@ -1,12 +1,24 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            require "bundler/gem_tasks"
         | 
| 4 | 
            +
            require "rubocop/rake_task"
         | 
| 4 5 | 
             
            require "rake/testtask"
         | 
| 5 6 |  | 
| 6 | 
            -
             | 
| 7 | 
            +
            RuboCop::RakeTask.new(:rubocop) do |t|
         | 
| 8 | 
            +
              t.options = ["--display-cop-names"]
         | 
| 9 | 
            +
            end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            Rake::TestTask.new("test:unit") do |t|
         | 
| 12 | 
            +
              t.libs << "test"
         | 
| 13 | 
            +
              t.libs << "lib"
         | 
| 14 | 
            +
              t.test_files = FileList["test/unit/**/*_test.rb"]
         | 
| 15 | 
            +
            end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            Rake::TestTask.new("test:integration") do |t|
         | 
| 7 18 | 
             
              t.libs << "test"
         | 
| 8 19 | 
             
              t.libs << "lib"
         | 
| 9 | 
            -
              t.test_files = FileList["test/**/*_test.rb"]
         | 
| 20 | 
            +
              t.test_files = FileList["test/integration/**/*_test.rb"]
         | 
| 10 21 | 
             
            end
         | 
| 11 22 |  | 
| 12 | 
            -
            task  | 
| 23 | 
            +
            task test: [:default]
         | 
| 24 | 
            +
            task default: ["test:integration", "test:unit", :rubocop]
         | 
    
        data/bin/console
    CHANGED
    
    | @@ -4,5 +4,34 @@ | |
| 4 4 | 
             
            require "bundler/setup"
         | 
| 5 5 | 
             
            require "redi_search"
         | 
| 6 6 |  | 
| 7 | 
            +
            require "faker"
         | 
| 7 8 | 
             
            require "pry"
         | 
| 9 | 
            +
            require "active_support/logger"
         | 
| 10 | 
            +
            require "active_record"
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            ActiveSupport::LogSubscriber.logger = ActiveSupport::Logger.new(STDOUT)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            ActiveRecord::Migration.create_table :users do |t|
         | 
| 17 | 
            +
              t.string :first
         | 
| 18 | 
            +
              t.string :last
         | 
| 19 | 
            +
            end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            class User < ActiveRecord::Base
         | 
| 22 | 
            +
              redi_search schema: {
         | 
| 23 | 
            +
                first: { text: { phonetic: "dm:en" } },
         | 
| 24 | 
            +
                last: { text: { phonetic: "dm:en" } }
         | 
| 25 | 
            +
              }
         | 
| 26 | 
            +
            end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            def seed_users(count = 10_000)
         | 
| 29 | 
            +
              User.insert_all(
         | 
| 30 | 
            +
                Array.new(count).map do
         | 
| 31 | 
            +
                  { first: Faker::Name.first_name, last: Faker::Name.last_name }
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              )
         | 
| 34 | 
            +
              User.reindex
         | 
| 35 | 
            +
            end
         | 
| 36 | 
            +
             | 
| 8 37 | 
             
            Pry.start
         | 
| @@ -2,16 +2,15 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            source "https://rubygems.org"
         | 
| 4 4 |  | 
| 5 | 
            +
            gem "appraisal", "~> 2.2"
         | 
| 5 6 | 
             
            gem "faker"
         | 
| 6 | 
            -
            gem "minitest", "~> 5.0"
         | 
| 7 7 | 
             
            gem "mocha"
         | 
| 8 8 | 
             
            gem "pry"
         | 
| 9 | 
            -
            gem "pry-rails"
         | 
| 10 9 | 
             
            gem "rubocop"
         | 
| 10 | 
            +
            gem "rubocop-minitest"
         | 
| 11 11 | 
             
            gem "rubocop-performance"
         | 
| 12 | 
            -
            gem "rubocop-rails"
         | 
| 13 12 | 
             
            gem "simplecov"
         | 
| 14 13 | 
             
            gem "sqlite3"
         | 
| 15 | 
            -
            gem " | 
| 14 | 
            +
            gem "activerecord", "< 5.2", ">= 5.1"
         | 
| 16 15 |  | 
| 17 16 | 
             
            gemspec path: "../"
         | 
| @@ -2,16 +2,15 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            source "https://rubygems.org"
         | 
| 4 4 |  | 
| 5 | 
            +
            gem "appraisal", "~> 2.2"
         | 
| 5 6 | 
             
            gem "faker"
         | 
| 6 | 
            -
            gem "minitest", "~> 5.0"
         | 
| 7 7 | 
             
            gem "mocha"
         | 
| 8 8 | 
             
            gem "pry"
         | 
| 9 | 
            -
            gem "pry-rails"
         | 
| 10 9 | 
             
            gem "rubocop"
         | 
| 10 | 
            +
            gem "rubocop-minitest"
         | 
| 11 11 | 
             
            gem "rubocop-performance"
         | 
| 12 | 
            -
            gem "rubocop-rails"
         | 
| 13 12 | 
             
            gem "simplecov"
         | 
| 14 13 | 
             
            gem "sqlite3"
         | 
| 15 | 
            -
            gem " | 
| 14 | 
            +
            gem "activerecord", "< 6.0", ">= 5.2"
         | 
| 16 15 |  | 
| 17 16 | 
             
            gemspec path: "../"
         |