Commit 71626568e01ad3d6ee73d63de976d6012cd46066

Authored by rainsense
1 parent bb4fa27c

make includes per model separate option, updated readme

README.md
... ... @@ -1630,6 +1630,13 @@ Eager load associations
1630 1630 Product.search "milk", includes: [:brand, :stores]
1631 1631 ```
1632 1632  
  1633 +Load associations per model
  1634 +
  1635 +```ruby
  1636 +Searchkick.search("*", index_name: [Product.search_index.name, Discount.search_index.name], includes_per: {Product => :store, Discount => :product})
  1637 +```
  1638 +These 2 options above can be combined, but you should make sure that associations specified by `includes` present in all searched models
  1639 +
1633 1640 Turn off special characters
1634 1641  
1635 1642 ```ruby
... ...
lib/searchkick/query.rb
... ... @@ -17,7 +17,7 @@ module Searchkick
17 17 def initialize(klass, term = "*", **options)
18 18 unknown_keywords = options.keys - [:aggs, :body, :body_options, :boost,
19 19 :boost_by, :boost_by_distance, :boost_where, :conversions, :conversions_term, :debug, :emoji, :exclude, :execute, :explain,
20   - :fields, :highlight, :includes, :index_name, :indices_boost, :limit, :load,
  20 + :fields, :highlight, :includes, :includes_per, :index_name, :indices_boost, :limit, :load,
21 21 :match, :misspellings, :offset, :operator, :order, :padding, :page, :per_page, :profile,
22 22 :request_params, :routing, :select, :similar, :smart_aggs, :suggest, :track, :type, :where]
23 23 raise ArgumentError, "unknown keywords: #{unknown_keywords.join(", ")}" if unknown_keywords.any?
... ... @@ -108,6 +108,7 @@ module Searchkick
108 108 padding: @padding,
109 109 load: @load,
110 110 includes: options[:includes],
  111 + includes_per: options[:includes_per],
111 112 json: !@json.nil?,
112 113 match_suffix: @match_suffix,
113 114 highlighted_fields: @highlighted_fields || [],
... ...
lib/searchkick/results.rb
... ... @@ -198,13 +198,13 @@ module Searchkick
198 198  
199 199 def results_query(records, hits)
200 200 ids = hits.map { |hit| hit["_id"] }
201   - if options[:includes]
  201 + if (options[:includes] || options[:includes_per])
202 202  
203   - included_relations = if options[:includes].is_a? Hash
204   - options[:includes][records]
205   - else
206   - options[:includes]
207   - end
  203 +
  204 + included_relations = []
  205 +
  206 + included_relations << options[:includes] if options[:includes]
  207 + included_relations << options[:includes_per][records] if (options[:includes_per] && options[:includes_per][records])
208 208  
209 209 records =
210 210 if defined?(NoBrainer::Document) && records < NoBrainer::Document
... ...
test/sql_test.rb
... ... @@ -195,19 +195,35 @@ class SqlTest &lt; Minitest::Test
195 195 assert Product.search("product", includes: [:store]).first.association(:store).loaded?
196 196 end
197 197  
198   - def test_includes_per_model
  198 + def test_includes_per
199 199 skip unless defined?(ActiveRecord)
200 200 store_names ["Product A"]
201 201 store_names ['Product A Discount'], Discount
202 202  
203   - associations = {Product => :store, Discount => :product}
  203 + associations = { Product => :store, Discount => :product }
204 204  
205   - result = Searchkick.search("product", fields: [:name], index_name: [Product.search_index.name, Discount.search_index.name], includes: associations)
206   -
207   - assert_equal 2, result.length
  205 + result = Searchkick.search("product", fields: [:name], index_name: [Product.search_index.name, Discount.search_index.name], includes_per: associations)
208 206  
209 207 result.group_by(&:class).each_pair do |klass, records|
210 208 assert records.first.association(associations[klass]).loaded?
211 209 end
212 210 end
  211 +
  212 + def test_both_includes
  213 + skip unless defined?(ActiveRecord)
  214 + store_names ["Product A"]
  215 + store_names ['Product A Discount'], Discount
  216 +
  217 + associations = { Discount => :product }
  218 +
  219 + result = Searchkick.search("product", fields: [:name], index_name: [Product.search_index.name, Discount.search_index.name], includes: [:store], includes_per: associations)
  220 +
  221 + assert_equal 2, result.length
  222 +
  223 + assert result.find{|record| record.class == Product}.association(:store).loaded?
  224 + assert result.find{|record| record.class == Discount}.association(:store).loaded?
  225 + assert result.find{|record| record.class == Discount}.association(:product).loaded?
  226 + end
  227 +
  228 +
213 229 end
... ...
test/test_helper.rb
... ... @@ -87,6 +87,7 @@ if defined?(Mongoid)
87 87 class Discount
88 88 include Mongoid::Document
89 89 belongs_to :product
  90 + belongs_to :store
90 91  
91 92 field :name
92 93 end
... ... @@ -161,6 +162,8 @@ elsif defined?(NoBrainer)
161 162 field :name, type: String
162 163  
163 164 belongs_to :product, validates: false
  165 + belongs_to :store, validates: false
  166 +
164 167 end
165 168  
166 169  
... ... @@ -372,6 +375,7 @@ else
372 375 ActiveRecord::Migration.create_table :discounts do |t|
373 376 t.string :name
374 377 t.integer :product_id
  378 + t.integer :store_id
375 379 end
376 380  
377 381 ActiveRecord::Migration.create_table :stores do |t|
... ... @@ -404,6 +408,7 @@ else
404 408  
405 409 class Discount < ActiveRecord::Base
406 410 belongs_to :product
  411 + belongs_to :store
407 412 end
408 413  
409 414 class Store < ActiveRecord::Base
... ... @@ -585,6 +590,7 @@ class Minitest::Test
585 590 def setup
586 591 Product.destroy_all
587 592 Store.destroy_all
  593 + Discount.destroy_all
588 594 Animal.destroy_all
589 595 Speaker.destroy_all
590 596 Sku.destroy_all
... ...