Commit 29fb877407db794e78d0cdb94a310f212662aa5c

Authored by Andrew Kane
1 parent 61673c48

Added relation class

lib/searchkick.rb
@@ -14,6 +14,7 @@ require "searchkick/query" @@ -14,6 +14,7 @@ require "searchkick/query"
14 require "searchkick/reindex_queue" 14 require "searchkick/reindex_queue"
15 require "searchkick/record_data" 15 require "searchkick/record_data"
16 require "searchkick/record_indexer" 16 require "searchkick/record_indexer"
  17 +require "searchkick/relation"
17 require "searchkick/results" 18 require "searchkick/results"
18 require "searchkick/version" 19 require "searchkick/version"
19 20
@@ -86,7 +87,7 @@ module Searchkick @@ -86,7 +87,7 @@ module Searchkick
86 @server_below7 87 @server_below7
87 end 88 end
88 89
89 - def self.search(term = "*", model: nil, **options, &block) 90 + def self.search(term = "*", model: nil, relation: false, **options, &block)
90 options = options.dup 91 options = options.dup
91 klass = model 92 klass = model
92 93
@@ -112,11 +113,15 @@ module Searchkick @@ -112,11 +113,15 @@ module Searchkick
112 end 113 end
113 114
114 options = options.merge(block: block) if block 115 options = options.merge(block: block) if block
115 - query = Searchkick::Query.new(klass, term, **options)  
116 - if options[:execute] == false  
117 - query 116 + if relation
  117 + Searchkick::Relation.new(klass, term, **options)
118 else 118 else
119 - query.execute 119 + query = Searchkick::Query.new(klass, term, **options)
  120 + if options[:execute] == false
  121 + query
  122 + else
  123 + query.execute
  124 + end
120 end 125 end
121 end 126 end
122 127
lib/searchkick/relation.rb 0 → 100644
@@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
  1 +module Searchkick
  2 + class Relation
  3 + extend Forwardable
  4 +
  5 + attr_reader :klass, :term, :options
  6 +
  7 + def_delegators :execute, :map, :each, :any?, :empty?, :size, :length, :slice, :[], :to_ary,
  8 + :records, :results, :suggestions, :each_with_hit, :with_details, :aggregations, :aggs,
  9 + :took, :error, :model_name, :entry_name, :total_count, :total_entries,
  10 + :current_page, :per_page, :limit_value, :padding, :total_pages, :num_pages,
  11 + :offset_value, :offset, :previous_page, :prev_page, :next_page, :first_page?, :last_page?,
  12 + :out_of_range?, :hits, :response, :to_a, :first, :scroll
  13 +
  14 + def initialize(klass, term = "*", **options)
  15 + unknown_keywords = options.keys - [:aggs, :block, :body, :body_options, :boost,
  16 + :boost_by, :boost_by_distance, :boost_by_recency, :boost_where, :conversions, :conversions_term, :debug, :emoji, :exclude, :execute, :explain,
  17 + :fields, :highlight, :includes, :index_name, :indices_boost, :limit, :load,
  18 + :match, :misspellings, :models, :model_includes, :offset, :operator, :order, :padding, :page, :per_page, :profile,
  19 + :request_params, :routing, :scope_results, :scroll, :select, :similar, :smart_aggs, :suggest, :total_entries, :track, :type, :where]
  20 + raise ArgumentError, "unknown keywords: #{unknown_keywords.join(", ")}" if unknown_keywords.any?
  21 +
  22 + @klass = klass
  23 + @term = term
  24 + @options = options
  25 + end
  26 +
  27 + def where(opts)
  28 + spawn.where!(opts)
  29 + end
  30 +
  31 + def where!(opts)
  32 + if options[:where]
  33 + options[:where] = [{_and: [options[:where], opts]}]
  34 + else
  35 + options[:where] = opts
  36 + end
  37 + self
  38 + end
  39 +
  40 + def limit(value)
  41 + spawn.limit!(value)
  42 + end
  43 +
  44 + def limit!(value)
  45 + options[:limit] = value
  46 + self
  47 + end
  48 +
  49 + # same as Active Record
  50 + def inspect
  51 + entries = results.first(11).map!(&:inspect)
  52 + entries[10] = "..." if entries.size == 11
  53 + "#<#{self.class.name} [#{entries.join(', ')}]>"
  54 + end
  55 +
  56 + private
  57 +
  58 + def execute
  59 + Query.new(klass, term, options).execute
  60 + end
  61 +
  62 + def spawn
  63 + Relation.new(klass, term, options.deep_dup)
  64 + end
  65 + end
  66 +end
test/relation_test.rb 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +require_relative "test_helper"
  2 +
  3 +class RelationTest < Minitest::Test
  4 + def test_works
  5 + store_names ["Product A", "Product B"]
  6 + p Product.search("product", relation: true).where(name: "Product A").limit(1)
  7 + end
  8 +
  9 + def test_no_term
  10 + store_names ["Product A"]
  11 + p Product.search(relation: true)
  12 + end
  13 +end