activesearch 0.0.7 → 0.0.8
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/README.md +21 -4
- data/activesearch.gemspec +1 -0
- data/lib/activesearch/base.rb +19 -13
- data/lib/activesearch/elastic_search.rb +15 -16
- data/lib/activesearch/mongoid.rb +4 -2
- data/lib/activesearch/version.rb +1 -1
- data/spec/base_spec.rb +68 -0
- data/spec/models/elastic_search.rb +2 -2
- data/spec/models/mongoid.rb +7 -3
- data/spec/mongoid_spec.rb +1 -1
- metadata +20 -2
data/README.md
CHANGED
@@ -21,12 +21,24 @@ It works by storing keywords taken from the specified fields and storing them in
|
|
21
21
|
|
22
22
|
##Configuration
|
23
23
|
|
24
|
-
|
24
|
+
call "search_by" from your model:
|
25
25
|
|
26
|
-
search_by :title, :body, store: [:slug]
|
27
|
-
|
28
|
-
|
26
|
+
search_by [:title, :body, store: [:slug]], if: :its_friday
|
27
|
+
|
28
|
+
**IMPORTANT: the first parameter must be either an array, or a symbol.
|
29
|
+
The second parameter must be a conditions hash.**
|
30
|
+
|
31
|
+
the :store option allows you to store that value in the index but it won't be used for search.
|
29
32
|
You can also add :if or :unless conditions in the same way you would do with ActiveModel callbacks.
|
33
|
+
If you need dynamic options, pass a symbol instead:
|
34
|
+
|
35
|
+
search_by :options_for_search
|
36
|
+
|
37
|
+
And define an instance method with that name which must return an array with the options, ie:
|
38
|
+
|
39
|
+
def options_for_search
|
40
|
+
[:field, :another_field]
|
41
|
+
end
|
30
42
|
|
31
43
|
## Querying
|
32
44
|
|
@@ -34,6 +46,11 @@ You can also add :if or :unless conditions in the same way you would do with Act
|
|
34
46
|
|
35
47
|
You can access the stored fields with to_hash, so you don't need to fetch the real document.
|
36
48
|
|
49
|
+
## Why?
|
50
|
+
|
51
|
+
You might wonder why you would like to use ActiveSearch instead of a specific option for your fulltext search index.
|
52
|
+
ActiveSearch provides an uniform API, which is in itself a drop-in replacement in case you want to move from an engine to another.
|
53
|
+
|
37
54
|
## Testing
|
38
55
|
|
39
56
|
Run specs with this command:
|
data/activesearch.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
20
|
gem.add_development_dependency "rspec"
|
21
|
+
gem.add_development_dependency "rspec-mocks"
|
21
22
|
gem.add_development_dependency "bson_ext"
|
22
23
|
gem.add_development_dependency "active_attr"
|
23
24
|
gem.add_development_dependency "mongoid", "~> 2"
|
data/lib/activesearch/base.rb
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
module ActiveSearch
|
2
2
|
module Base
|
3
|
-
def
|
4
|
-
|
5
|
-
self.after_save :reindex, self.search_conditions
|
6
|
-
self.after_destroy :deindex, self.search_conditions
|
3
|
+
def self.included(parent)
|
4
|
+
parent.extend ClassMethods
|
7
5
|
end
|
8
6
|
|
9
7
|
def search_options
|
10
8
|
search_parameters.last.is_a?(Hash) ? search_parameters.last : {}
|
11
9
|
end
|
12
10
|
|
13
|
-
def search_conditions
|
14
|
-
{}.tap do |conditions|
|
15
|
-
conditions.merge!(if: search_options[:if]) if search_options.has_key?(:if)
|
16
|
-
conditions.merge!(unless: search_options[:unless]) if search_options.has_key?(:unless)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
11
|
def search_fields
|
21
12
|
search_parameters.last.is_a?(Hash) ? search_parameters[0...-1] : search_parameters
|
22
13
|
end
|
23
14
|
|
24
|
-
protected
|
25
15
|
def search_parameters
|
26
|
-
|
16
|
+
if self.class.search_parameters.is_a?(Symbol)
|
17
|
+
self.send(self.class.search_parameters)
|
18
|
+
else
|
19
|
+
self.class.search_parameters
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
def search_by(params, conditions = {})
|
25
|
+
after_save :reindex, conditions
|
26
|
+
after_destroy :deindex, conditions
|
27
|
+
@search_parameters = params
|
28
|
+
end
|
29
|
+
|
30
|
+
def search_parameters
|
31
|
+
@search_parameters
|
32
|
+
end
|
27
33
|
end
|
28
34
|
end
|
29
35
|
end
|
@@ -11,8 +11,9 @@ module ActiveSearch
|
|
11
11
|
|
12
12
|
module ElasticSearch
|
13
13
|
def self.included(base)
|
14
|
-
base.
|
15
|
-
|
14
|
+
base.class_eval do
|
15
|
+
include ActiveSearch::Base
|
16
|
+
end
|
16
17
|
end
|
17
18
|
|
18
19
|
def to_indexable
|
@@ -30,7 +31,7 @@ module ActiveSearch
|
|
30
31
|
|
31
32
|
def reindex
|
32
33
|
doc = self.to_indexable
|
33
|
-
properties = self.
|
34
|
+
properties = self.elastic_properties
|
34
35
|
|
35
36
|
elastic_index do
|
36
37
|
unless exists?
|
@@ -47,20 +48,18 @@ module ActiveSearch
|
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
hash[field] = {type: 'string'}
|
56
|
-
end
|
57
|
-
|
58
|
-
(Array(search_options[:store]) - search_fields).each_with_object(props) do |field,hash|
|
59
|
-
hash[field] = {type: 'string', :index => :no}
|
60
|
-
end
|
61
|
-
|
62
|
-
props
|
51
|
+
def elastic_properties
|
52
|
+
props = {}
|
53
|
+
|
54
|
+
search_fields.each_with_object(props) do |field,hash|
|
55
|
+
hash[field] = {type: 'string'}
|
63
56
|
end
|
57
|
+
|
58
|
+
(Array(search_options[:store]) - search_fields).each_with_object(props) do |field,hash|
|
59
|
+
hash[field] = {type: 'string', :index => :no}
|
60
|
+
end
|
61
|
+
|
62
|
+
props
|
64
63
|
end
|
65
64
|
end
|
66
65
|
end
|
data/lib/activesearch/mongoid.rb
CHANGED
@@ -11,12 +11,14 @@ module ActiveSearch
|
|
11
11
|
|
12
12
|
module Mongoid
|
13
13
|
def self.included(base)
|
14
|
-
base.
|
14
|
+
base.class_eval do
|
15
|
+
include Base
|
16
|
+
end
|
15
17
|
end
|
16
18
|
|
17
19
|
protected
|
18
20
|
def reindex
|
19
|
-
ActiveSearch::Mongoid::Model.reindex(self, self.
|
21
|
+
ActiveSearch::Mongoid::Model.reindex(self, self.search_fields, self.search_options)
|
20
22
|
end
|
21
23
|
|
22
24
|
def deindex
|
data/lib/activesearch/version.rb
CHANGED
data/spec/base_spec.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'activesearch/base'
|
2
|
+
|
3
|
+
describe ActiveSearch::Base do
|
4
|
+
before do
|
5
|
+
@klass = Class.new do
|
6
|
+
include ActiveSearch::Base
|
7
|
+
|
8
|
+
def self.after_save(*args); end
|
9
|
+
def self.after_destroy(*args); end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "search_by" do
|
15
|
+
let(:call_search_by) do
|
16
|
+
@klass.class_eval do
|
17
|
+
search_by [:field], if: :something_happens, unless: :its_friday
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should rely on after_save and after_destroy callbacks passing conditions" do
|
22
|
+
@klass.should_receive(:after_save).with(:reindex, if: :something_happens, unless: :its_friday)
|
23
|
+
@klass.should_receive(:after_destroy).with(:deindex, if: :something_happens, unless: :its_friday)
|
24
|
+
call_search_by
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should store the parameters in search_parameters" do
|
28
|
+
call_search_by
|
29
|
+
@klass.send(:search_parameters).should == [:field]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "utility methods with options" do
|
34
|
+
before do
|
35
|
+
@klass.stub(:search_parameters).and_return([:field, store: [:another_field]])
|
36
|
+
end
|
37
|
+
|
38
|
+
it "search_options should return the hash at the end of the parameters" do
|
39
|
+
@klass.new.search_options.should == {store: [:another_field]}
|
40
|
+
end
|
41
|
+
|
42
|
+
it "search_fields should return all parameters except the options" do
|
43
|
+
@klass.new.search_fields.should == [:field]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "search_by with dynamic parameters" do
|
48
|
+
before do
|
49
|
+
@klass.class_eval do
|
50
|
+
def options_for_search
|
51
|
+
[@field]
|
52
|
+
end
|
53
|
+
|
54
|
+
def initialize(field)
|
55
|
+
@field = field
|
56
|
+
end
|
57
|
+
|
58
|
+
search_by :options_for_search
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should work" do
|
63
|
+
@klass.new(:first).send(:search_parameters).should == [:first]
|
64
|
+
@klass.new(:second).send(:search_parameters).should == [:second]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -20,7 +20,7 @@ class ElasticSearchModel < ActiveMimic
|
|
20
20
|
attribute :junk
|
21
21
|
attribute :special, default: false
|
22
22
|
|
23
|
-
search_by :title, :text, store: [:title, :junk], if: lambda { !self.special }
|
23
|
+
search_by [:title, :text, store: [:title, :junk]], if: lambda { !self.special }
|
24
24
|
|
25
25
|
end
|
26
26
|
|
@@ -29,5 +29,5 @@ class AnotherElasticSearchModel < ActiveMimic
|
|
29
29
|
include ElasticSearchRefresh
|
30
30
|
|
31
31
|
attribute :title, type: String
|
32
|
-
search_by :title, store: [:title]
|
32
|
+
search_by [:title, store: [:title]]
|
33
33
|
end
|
data/spec/models/mongoid.rb
CHANGED
@@ -11,7 +11,7 @@ class MongoidModel
|
|
11
11
|
field :text, type: String
|
12
12
|
field :junk, type: String
|
13
13
|
field :special, type: Boolean, default: false
|
14
|
-
search_by :title, :text, store: [:title, :junk], unless: :special
|
14
|
+
search_by [:title, :text, store: [:title, :junk]], unless: :special
|
15
15
|
end
|
16
16
|
|
17
17
|
class AnotherMongoidModel
|
@@ -19,7 +19,11 @@ class AnotherMongoidModel
|
|
19
19
|
include ActiveSearch::Mongoid
|
20
20
|
|
21
21
|
field :title, type: String
|
22
|
-
search_by
|
22
|
+
search_by :options_for_search
|
23
|
+
|
24
|
+
def options_for_search
|
25
|
+
[:title, :text, store: [:title]]
|
26
|
+
end
|
23
27
|
end
|
24
28
|
|
25
29
|
|
@@ -29,5 +33,5 @@ class LocalizedMongoidModel
|
|
29
33
|
|
30
34
|
field :title, localize: true
|
31
35
|
field :special_type
|
32
|
-
search_by :title, store: [:title]
|
36
|
+
search_by [:title, store: [:title]]
|
33
37
|
end
|
data/spec/mongoid_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activesearch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec-mocks
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
30
46
|
- !ruby/object:Gem::Dependency
|
31
47
|
name: bson_ext
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,6 +144,7 @@ files:
|
|
128
144
|
- lib/activesearch/mongoid/model.rb
|
129
145
|
- lib/activesearch/result.rb
|
130
146
|
- lib/activesearch/version.rb
|
147
|
+
- spec/base_spec.rb
|
131
148
|
- spec/config/mongoid.yml
|
132
149
|
- spec/engines_spec.rb
|
133
150
|
- spec/models/elastic_search.rb
|
@@ -160,6 +177,7 @@ specification_version: 3
|
|
160
177
|
summary: ActiveSearch lets you plug in a ruby module in any class that will allow
|
161
178
|
you to do full text searches.
|
162
179
|
test_files:
|
180
|
+
- spec/base_spec.rb
|
163
181
|
- spec/config/mongoid.yml
|
164
182
|
- spec/engines_spec.rb
|
165
183
|
- spec/models/elastic_search.rb
|