scoped_search 2.3.1 → 2.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +14 -12
- data/lib/scoped_search/auto_complete_builder.rb +12 -5
- data/lib/scoped_search/definition.rb +2 -2
- data/lib/scoped_search/query_builder.rb +1 -1
- data/lib/scoped_search/rails_helper.rb +1 -1
- data/lib/scoped_search.rb +1 -1
- data/scoped_search.gemspec +2 -2
- data/spec/integration/ordinal_querying_spec.rb +7 -3
- data/spec/lib/database.rb +2 -1
- metadata +9 -3
data/README.rdoc
CHANGED
@@ -5,27 +5,28 @@ models. Searching is performed using a query string, which should be passed to
|
|
5
5
|
the named_scope <tt>search_for</tt>. Based on a definition in what fields to
|
6
6
|
look, it will build query conditions and return those as a named scope.
|
7
7
|
|
8
|
-
Scoped search is great if you want to offer a simple search box to your users
|
9
|
-
and build a query based on the search string they enter.
|
10
|
-
|
11
|
-
|
8
|
+
Scoped search is great if you want to offer a simple yet powerful search box to your users
|
9
|
+
and build a query based on the search string they enter. It comes with a built-in search syntax
|
10
|
+
auto-completer and a value auto-completer. It also comes with a set of helpers that makes it easy
|
11
|
+
to create a clean web UI with sorting and an ajax auto-completer.
|
12
|
+
|
13
|
+
== Preview
|
14
|
+
A demo application using the scoped search can be found here: http://github.com/abenari/scoped_search_demo_app
|
15
|
+
A running version of the demo application can be found here: http://scope-search-demo.heroku.com
|
12
16
|
|
13
17
|
== Installing
|
18
|
+
For a Rails 3 application add the following line in your Gemfile, and run <tt>bundle install</tt>:
|
19
|
+
|
20
|
+
gem "scoped_search"
|
14
21
|
|
15
|
-
|
16
|
-
|
17
|
-
configuration in <tt>config/environment.rb</tt>, and run <tt>rake
|
18
|
-
gems:install</tt> to install the gem.:
|
22
|
+
For Rails 2 Add the following code to your Rails configuration in <tt>config/environment.rb</tt>,
|
23
|
+
and run <tt>rake gems:install</tt> to install the gem.:
|
19
24
|
|
20
25
|
Rails::Initializer.run do |config|
|
21
26
|
...
|
22
27
|
config.gem 'scoped_search'
|
23
28
|
end
|
24
29
|
|
25
|
-
Alternatively, install scoped search as a Rails plugin (*deprecated*):
|
26
|
-
|
27
|
-
script/plugin install git://github.com/wvanbergen/scoped_search.git
|
28
|
-
|
29
30
|
== Usage
|
30
31
|
|
31
32
|
Scoped search requires you to define the fields you want to search in:
|
@@ -119,6 +120,7 @@ For more info, see the the project wiki: http://github.com/wvanbergen/scoped_sea
|
|
119
120
|
* Issue tracker: http://github.com/wvanbergen/scoped_search/issues
|
120
121
|
* RDoc documentation: http://rdoc.info/projects/wvanbergen/scoped_search
|
121
122
|
* wvanbergen's blog posts: http://techblog.floorplanner.com/tag/scoped_search
|
123
|
+
* abenari's blog: http://scopedsearch.wordpress.com/
|
122
124
|
|
123
125
|
== License
|
124
126
|
|
@@ -16,18 +16,19 @@ module ScopedSearch
|
|
16
16
|
|
17
17
|
# This method will parse the query string and build suggestion list using the
|
18
18
|
# search query.
|
19
|
-
def self.auto_complete(definition, query)
|
19
|
+
def self.auto_complete(definition, query, options = {})
|
20
20
|
return [] if (query.nil? or definition.nil? or !definition.respond_to?(:fields))
|
21
21
|
|
22
|
-
new(definition, query).build_autocomplete_options
|
22
|
+
new(definition, query, options).build_autocomplete_options
|
23
23
|
end
|
24
24
|
|
25
25
|
# Initializes the instance by setting the relevant parameters
|
26
|
-
def initialize(definition, query)
|
26
|
+
def initialize(definition, query, options)
|
27
27
|
@definition = definition
|
28
28
|
@ast = ScopedSearch::QueryLanguage::Compiler.parse(query)
|
29
29
|
@query = query
|
30
30
|
@tokens = tokenize
|
31
|
+
@options = options
|
31
32
|
end
|
32
33
|
|
33
34
|
# Test the validity of the current query and suggest possible completion
|
@@ -191,7 +192,13 @@ module ScopedSearch
|
|
191
192
|
|
192
193
|
opts = value_conditions(field.field, val)
|
193
194
|
opts.merge!(:limit => 20, :select => "DISTINCT #{field.field}")
|
194
|
-
|
195
|
+
|
196
|
+
return completer_scope(field.klass).all(opts).map(&field.field).compact.map{|v| v.to_s =~ /\s+/ ? "\"#{v}\"" : v}
|
197
|
+
end
|
198
|
+
|
199
|
+
def completer_scope(klass)
|
200
|
+
return klass unless klass.respond_to?(:completer_scope)
|
201
|
+
klass.completer_scope(@options)
|
195
202
|
end
|
196
203
|
|
197
204
|
# set value completer
|
@@ -230,7 +237,7 @@ module ScopedSearch
|
|
230
237
|
else
|
231
238
|
opts.merge!(key_opts)
|
232
239
|
end
|
233
|
-
return field.klass.all(opts.merge(:limit => 20)).map(&field.field).compact.map{|v| v.to_s =~ /\s+/ ? "\"#{v}\"" : v}
|
240
|
+
return completer_scope(field.klass).all(opts.merge(:limit => 20)).map(&field.field).compact.map{|v| v.to_s =~ /\s+/ ? "\"#{v}\"" : v}
|
234
241
|
end
|
235
242
|
|
236
243
|
#this method returns conditions for selecting completion from partial value
|
@@ -250,8 +250,8 @@ end
|
|
250
250
|
# Registers the complete_for method within the class that is used for searching.
|
251
251
|
def register_complete_for! # :nodoc
|
252
252
|
@klass.class_eval do
|
253
|
-
def self.complete_for (query)
|
254
|
-
search_options = ScopedSearch::AutoCompleteBuilder.auto_complete(@scoped_search , query)
|
253
|
+
def self.complete_for (query, options = {})
|
254
|
+
search_options = ScopedSearch::AutoCompleteBuilder.auto_complete(@scoped_search , query, options)
|
255
255
|
search_options
|
256
256
|
end
|
257
257
|
end
|
@@ -206,7 +206,7 @@ module ScopedSearch
|
|
206
206
|
elsif field.set?
|
207
207
|
return set_test(field, operator, value, &block)
|
208
208
|
else
|
209
|
-
value = value.to_i if field.
|
209
|
+
value = value.to_i if field.offset
|
210
210
|
yield(:parameter, value)
|
211
211
|
return "#{field.to_sql(operator, &block)} #{self.sql_operator(operator, field)} ?"
|
212
212
|
end
|
@@ -200,7 +200,7 @@ module ScopedSearch
|
|
200
200
|
# In your controller, you'll need to define an action called
|
201
201
|
# auto_complete_method to respond the JQuery calls,
|
202
202
|
def auto_complete_field_tag_jquery(method, val,tag_options = {}, completion_options = {})
|
203
|
-
url = url_for(:action => "auto_complete_#{method}")
|
203
|
+
url = url_for(:action => "auto_complete_#{method}", :filter => completion_options[:filter])
|
204
204
|
options = tag_options.merge(:class => "auto_complete_input")
|
205
205
|
text_field_tag(method, val, options) + auto_complete_clear_value_button(method) +
|
206
206
|
auto_complete_field_jquery(method, url, completion_options)
|
data/lib/scoped_search.rb
CHANGED
@@ -14,7 +14,7 @@ module ScopedSearch
|
|
14
14
|
|
15
15
|
# The current scoped_search version. Do not change thisvalue by hand,
|
16
16
|
# because it will be updated automatically by the gem release script.
|
17
|
-
VERSION = "2.3.
|
17
|
+
VERSION = "2.3.3"
|
18
18
|
|
19
19
|
# The ClassMethods module will be included into the ActiveRecord::Base class
|
20
20
|
# to add the <tt>ActiveRecord::Base.scoped_search</tt> method and the
|
data/scoped_search.gemspec
CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
|
|
3
3
|
|
4
4
|
# Do not change the version and date fields by hand. This will be done
|
5
5
|
# automatically by the gem release script.
|
6
|
-
s.version = "2.3.
|
7
|
-
s.date = "2011-06
|
6
|
+
s.version = "2.3.3"
|
7
|
+
s.date = "2011-09-06"
|
8
8
|
|
9
9
|
s.summary = "Easily search you ActiveRecord models with a simple query language using a named scope."
|
10
10
|
s.description = <<-EOS
|
@@ -9,8 +9,8 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
9
9
|
before(:all) do
|
10
10
|
ScopedSearch::RSpec::Database.establish_named_connection(db)
|
11
11
|
|
12
|
-
@class = ScopedSearch::RSpec::Database.create_model(:int => :integer, :timestamp => :datetime, :date => :date, :unindexed => :integer) do |klass|
|
13
|
-
klass.scoped_search :on => [:int, :timestamp]
|
12
|
+
@class = ScopedSearch::RSpec::Database.create_model(:int => :integer, :dec => :decimal ,:timestamp => :datetime, :date => :date, :unindexed => :integer) do |klass|
|
13
|
+
klass.scoped_search :on => [:int, :dec, :timestamp]
|
14
14
|
klass.scoped_search :on => :date, :only_explicit => true
|
15
15
|
end
|
16
16
|
end
|
@@ -23,7 +23,7 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
23
23
|
context 'querying numerical fields' do
|
24
24
|
|
25
25
|
before(:all) do
|
26
|
-
@record = @class.create!(:int => 9)
|
26
|
+
@record = @class.create!(:int => 9, :dec => 1.23)
|
27
27
|
end
|
28
28
|
|
29
29
|
after(:all) do
|
@@ -34,6 +34,10 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
34
34
|
@class.search_for('9').should have(1).item
|
35
35
|
end
|
36
36
|
|
37
|
+
it "should find the record with an exact decimal match" do
|
38
|
+
@class.search_for('1.23').should have(1).item
|
39
|
+
end
|
40
|
+
|
37
41
|
it "should find the record with an exact integer match with an explicit operator" do
|
38
42
|
@class.search_for('= 9').should have(1).item
|
39
43
|
end
|
data/spec/lib/database.rb
CHANGED
@@ -37,7 +37,8 @@ module ScopedSearch::RSpec::Database
|
|
37
37
|
table_name = "model_#{rand}".gsub(/\./, '')
|
38
38
|
ActiveRecord::Migration.create_table(table_name) do |t|
|
39
39
|
fields.each do |name, field_type|
|
40
|
-
|
40
|
+
options = (field_type == :decimal) ? { :scale => 2, :precision => 10 } : {}
|
41
|
+
t.send(field_type.to_s.gsub(/^unindexed_/, '').to_sym, name, options)
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scoped_search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 5
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 2
|
7
8
|
- 3
|
8
|
-
-
|
9
|
-
version: 2.3.
|
9
|
+
- 3
|
10
|
+
version: 2.3.3
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Willem van Bergen
|
@@ -15,7 +16,7 @@ autorequire:
|
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
18
|
|
18
|
-
date: 2011-06
|
19
|
+
date: 2011-09-06 00:00:00 +03:00
|
19
20
|
default_executable:
|
20
21
|
dependencies:
|
21
22
|
- !ruby/object:Gem::Dependency
|
@@ -26,6 +27,7 @@ dependencies:
|
|
26
27
|
requirements:
|
27
28
|
- - ">="
|
28
29
|
- !ruby/object:Gem::Version
|
30
|
+
hash: 11
|
29
31
|
segments:
|
30
32
|
- 2
|
31
33
|
- 1
|
@@ -41,6 +43,7 @@ dependencies:
|
|
41
43
|
requirements:
|
42
44
|
- - ~>
|
43
45
|
- !ruby/object:Gem::Version
|
46
|
+
hash: 3
|
44
47
|
segments:
|
45
48
|
- 2
|
46
49
|
- 0
|
@@ -55,6 +58,7 @@ dependencies:
|
|
55
58
|
requirements:
|
56
59
|
- - ">="
|
57
60
|
- !ruby/object:Gem::Version
|
61
|
+
hash: 3
|
58
62
|
segments:
|
59
63
|
- 0
|
60
64
|
version: "0"
|
@@ -127,6 +131,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
127
131
|
requirements:
|
128
132
|
- - ">="
|
129
133
|
- !ruby/object:Gem::Version
|
134
|
+
hash: 3
|
130
135
|
segments:
|
131
136
|
- 0
|
132
137
|
version: "0"
|
@@ -135,6 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
140
|
requirements:
|
136
141
|
- - ">="
|
137
142
|
- !ruby/object:Gem::Version
|
143
|
+
hash: 3
|
138
144
|
segments:
|
139
145
|
- 0
|
140
146
|
version: "0"
|