stretchy 0.4.3 → 0.4.4
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/README.md +10 -1
- data/lib/stretchy/boosts/field_decay_boost.rb +1 -1
- data/lib/stretchy/boosts/field_value_boost.rb +2 -2
- data/lib/stretchy/boosts/filter_boost.rb +2 -2
- data/lib/stretchy/builders/match_builder.rb +4 -0
- data/lib/stretchy/builders/query_builder.rb +12 -3
- data/lib/stretchy/builders/shell_builder.rb +5 -0
- data/lib/stretchy/clauses/base.rb +31 -1
- data/lib/stretchy/clauses/boost_clause.rb +1 -2
- data/lib/stretchy/clauses/boost_match_clause.rb +2 -3
- data/lib/stretchy/clauses/match_clause.rb +46 -1
- data/lib/stretchy/filters/base.rb +2 -0
- data/lib/stretchy/filters/exists_filter.rb +1 -1
- data/lib/stretchy/filters/geo_filter.rb +1 -1
- data/lib/stretchy/filters/range_filter.rb +1 -1
- data/lib/stretchy/filters/terms_filter.rb +1 -1
- data/lib/stretchy/queries/filtered_query.rb +2 -2
- data/lib/stretchy/queries/match_query.rb +2 -2
- data/lib/stretchy/queries/more_like_this_query.rb +57 -0
- data/lib/stretchy/queries.rb +1 -0
- data/lib/stretchy/utils/validation.rb +4 -0
- data/lib/stretchy/version.rb +1 -1
- data/lib/stretchy_validations.rb +2 -0
- data/lib/validation/rule/decay.rb +1 -6
- data/lib/validation/rule/distance.rb +1 -6
- data/lib/validation/rule/field.rb +9 -8
- data/lib/validation/rule/inclusion.rb +3 -11
- data/lib/validation/rule/latitude.rb +1 -5
- data/lib/validation/rule/longitude.rb +1 -6
- data/lib/validation/rule/min_should_match.rb +18 -0
- data/lib/validation/rule/required.rb +2 -14
- data/lib/validation/rule/responds_to.rb +1 -10
- data/lib/validation/rule/stretchy_rule.rb +38 -0
- data/lib/validation/rule/type.rb +7 -20
- data/solano.yml +9 -0
- metadata +6 -4
- data/.travis.yml +0 -6
- data/lib/validation/rule/one_of.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0bc5fc45426e803f3fe65879afb93ed01e654e32
|
4
|
+
data.tar.gz: a5edc4764c1e5760b7fcd5458de681085ee2397d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a9fbf2f0ca614fd6e6049acf79cdc63309395ba97d44cae7c4b9a2c284744c3f523871453e525655cddf81e96909b0ce429712c8cebad5a83d8ae01952864ee
|
7
|
+
data.tar.gz: 6a7404a23251bdbf7b728c9d33c0a72b455a93ac0c16fb014fcbcc328ee918b01a75603ba5b308f7b2df3974c161fbc2efa0499051e5ce747b43ef117ad224bf
|
data/README.md
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# Stretchy
|
2
|
-
[](https://travis-ci.org/hired/stretchy)
|
3
2
|
|
4
3
|
Stretchy is a query builder for [Elasticsearch](https://www.elastic.co/products/elasticsearch). It helps you quickly construct the JSON to send to Elastic, which can get [rather complicated](http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html).
|
5
4
|
|
@@ -81,6 +80,16 @@ query = query.match('welcome to my web site')
|
|
81
80
|
|
82
81
|
Performs a match query for the given string. If given a hash, it will use a match query on the specified fields, otherwise it will default to `'_all'`. By default, a match query searches for any of the analyzed terms in the document, and scores them using Lucene's [practical scoring formula](https://www.elastic.co/guide/en/elasticsearch/guide/current/practical-scoring-function.html), which combines TF/IDF, the vector space model, and a few other niceties.
|
83
82
|
|
83
|
+
### More Like
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
query = query.more_like(ids: [1, 2, 3])
|
87
|
+
.more_like(docs: other_search.results)
|
88
|
+
.more_like(like_text: 'puppies and kittens are great', fields: :about_me)
|
89
|
+
```
|
90
|
+
|
91
|
+
Finds documents similar to a list of input documents. You must pass in one of the `:ids`, `:docs` or `:like_text` parameters, but everything else is optional. This method accepts any of the params available in the [Elasticsearch more_like_this query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-mlt-query.html). It can also be chained with `.not` and `.should`.
|
92
|
+
|
84
93
|
### Where
|
85
94
|
|
86
95
|
```ruby
|
@@ -16,7 +16,7 @@ module Stretchy
|
|
16
16
|
attribute :weight
|
17
17
|
|
18
18
|
validations do
|
19
|
-
rule :field,
|
19
|
+
rule :field, field: { required: true }
|
20
20
|
rule :origin, type: {classes: [Numeric, Time, Date, Stretchy::Types::GeoPoint], required: true}
|
21
21
|
rule :scale, :required
|
22
22
|
rule :decay, :decay
|
@@ -9,9 +9,9 @@ module Stretchy
|
|
9
9
|
attribute :factor
|
10
10
|
|
11
11
|
validations do
|
12
|
-
rule :field, :
|
12
|
+
rule :field, field: { required: true }
|
13
13
|
rule :modifier, inclusion: {in: MODIFIERS}
|
14
|
-
rule :factor,
|
14
|
+
rule :factor, type: {classes: Numeric}
|
15
15
|
end
|
16
16
|
|
17
17
|
def initialize(field, options = {})
|
@@ -9,8 +9,8 @@ module Stretchy
|
|
9
9
|
attribute :weight, Numeric, default: DEFAULT_WEIGHT
|
10
10
|
|
11
11
|
validations do
|
12
|
-
rule :filter, type:
|
13
|
-
rule :weight, type:
|
12
|
+
rule :filter, type: Filters::Base
|
13
|
+
rule :weight, type: Numeric
|
14
14
|
end
|
15
15
|
|
16
16
|
def initialize(options = {})
|
@@ -15,6 +15,10 @@ module Stretchy
|
|
15
15
|
must.any? || must_not.any? || should.any? || should_not.any?
|
16
16
|
end
|
17
17
|
|
18
|
+
def add_query(query, options = {})
|
19
|
+
builder_from_options(options).add_query(query)
|
20
|
+
end
|
21
|
+
|
18
22
|
def add_matches(field, matches, options = {})
|
19
23
|
builder_from_options(options).add_matches(field, matches, options)
|
20
24
|
end
|
@@ -4,15 +4,20 @@ module Stretchy
|
|
4
4
|
|
5
5
|
extend Forwardable
|
6
6
|
|
7
|
-
delegate [:any?, :count, :length] => :
|
7
|
+
delegate [:any?, :count, :length] => :to_enum
|
8
8
|
|
9
|
-
attr_reader :matches, :query_opts
|
9
|
+
attr_reader :queries, :matches, :query_opts
|
10
10
|
|
11
11
|
def initialize
|
12
|
+
@queries = []
|
12
13
|
@matches = Hash.new { [] }
|
13
14
|
@query_opts = Hash.new { {} }
|
14
15
|
end
|
15
16
|
|
17
|
+
def add_query(query)
|
18
|
+
@queries << query
|
19
|
+
end
|
20
|
+
|
16
21
|
def add_matches(field, new_matches, options = {})
|
17
22
|
@matches[field] += Array(new_matches)
|
18
23
|
opts = {}
|
@@ -22,8 +27,12 @@ module Stretchy
|
|
22
27
|
@query_opts[field] = opts
|
23
28
|
end
|
24
29
|
|
30
|
+
def to_enum
|
31
|
+
queries + matches.values
|
32
|
+
end
|
33
|
+
|
25
34
|
def to_queries
|
26
|
-
matches.map do |field, phrases|
|
35
|
+
queries + matches.map do |field, phrases|
|
27
36
|
opts = query_opts[field].merge(
|
28
37
|
field: field,
|
29
38
|
string: phrases.flatten.join(' ')
|
@@ -2,6 +2,8 @@ module Stretchy
|
|
2
2
|
module Builders
|
3
3
|
class ShellBuilder
|
4
4
|
|
5
|
+
extend Forwardable
|
6
|
+
|
5
7
|
DEFAULT_LIMIT = 30
|
6
8
|
DEFAULT_OFFSET = 0
|
7
9
|
|
@@ -9,6 +11,9 @@ module Stretchy
|
|
9
11
|
:match_builder, :where_builder, :boost_builder,
|
10
12
|
:aggregate_builder, :fields
|
11
13
|
|
14
|
+
delegate [:add_matches, :add_query] => :match_builder
|
15
|
+
delegate [:add_param, :add_geo, :add_range] => :where_builder
|
16
|
+
|
12
17
|
def initialize(options = {})
|
13
18
|
@index = options[:index] || Stretchy.index_name
|
14
19
|
@match_builder = Stretchy::Builders::MatchBuilder.new
|
@@ -22,7 +22,7 @@ module Stretchy
|
|
22
22
|
:took, :shards, :total, :max_score, :total_pages] => :query_results
|
23
23
|
delegate [:to_search] => :base
|
24
24
|
delegate [:where, :range, :geo, :terms, :not] => :build_where
|
25
|
-
delegate [:match, :fulltext] => :build_match
|
25
|
+
delegate [:match, :fulltext, :more_like] => :build_match
|
26
26
|
|
27
27
|
#
|
28
28
|
# Generates a chainable query. The only required option for the
|
@@ -49,6 +49,23 @@ module Stretchy
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
#
|
53
|
+
# Exits any state the query is in (boost, inverse, should, etc)
|
54
|
+
# and returns to the root query state. You can use this before
|
55
|
+
# calling `.where` or other overridden methods to ensure they
|
56
|
+
# are being processed from the base state.
|
57
|
+
#
|
58
|
+
# If you have to call this method, please file an issue.
|
59
|
+
# End-of-chain methods (such as `.boost.where.not()`) should
|
60
|
+
# always return to the root state, and state is not
|
61
|
+
# something you should have to think about.
|
62
|
+
#
|
63
|
+
# @return [Base] Continue the query chain from the root state
|
64
|
+
#
|
65
|
+
def root
|
66
|
+
Base.new(base)
|
67
|
+
end
|
68
|
+
|
52
69
|
#
|
53
70
|
# Sets how many results to return, similar to
|
54
71
|
# ActiveRecord's limit method.
|
@@ -160,6 +177,19 @@ module Stretchy
|
|
160
177
|
!!base.explain
|
161
178
|
end
|
162
179
|
|
180
|
+
#
|
181
|
+
# Filter for documents that do not match the specified fields and values
|
182
|
+
#
|
183
|
+
# @overload not(params)
|
184
|
+
# @param [String] A string that must not be matched anywhere in the document
|
185
|
+
# @overload not(params)
|
186
|
+
# @param [Hash] A hash of fields and strings or terms that must not be matched in those fields
|
187
|
+
#
|
188
|
+
# @return [MatchClause, WhereClause] inverted query state with match filters applied
|
189
|
+
#
|
190
|
+
# @see {MatchClause#not}
|
191
|
+
# @see {WhereClause#not}
|
192
|
+
#
|
163
193
|
def not(params = {}, options = {})
|
164
194
|
if params.is_a?(String)
|
165
195
|
build_match.not(params, options)
|
@@ -76,10 +76,9 @@ module Stretchy
|
|
76
76
|
def field(*args)
|
77
77
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
78
78
|
args.each do |field|
|
79
|
-
pp
|
80
79
|
base.boost_builder.add_boost(Boosts::FieldValueBoost.new(field, options))
|
81
80
|
end
|
82
|
-
|
81
|
+
Base.new(base)
|
83
82
|
end
|
84
83
|
|
85
84
|
def not(*args)
|
@@ -30,12 +30,10 @@ module Stretchy
|
|
30
30
|
def not(params = {})
|
31
31
|
@inverse = true
|
32
32
|
match_function(hashify_params(params))
|
33
|
-
self
|
34
33
|
end
|
35
34
|
|
36
35
|
def boost_match(params = {}, options = {})
|
37
36
|
match_function(hashify_params(params), options)
|
38
|
-
self
|
39
37
|
end
|
40
38
|
|
41
39
|
def fulltext(params = {}, options = {})
|
@@ -45,7 +43,7 @@ module Stretchy
|
|
45
43
|
clause = MatchClause.new.match(params, options)
|
46
44
|
boost = clause.to_boost(weight)
|
47
45
|
base.boost_builder.add_boost(boost) if boost
|
48
|
-
|
46
|
+
Base.new(base)
|
49
47
|
end
|
50
48
|
|
51
49
|
#
|
@@ -89,6 +87,7 @@ module Stretchy
|
|
89
87
|
clause = MatchClause.new.match(params, options)
|
90
88
|
boost = clause.to_boost(weight)
|
91
89
|
base.boost_builder.add_boost(boost) if boost
|
90
|
+
self
|
92
91
|
end
|
93
92
|
|
94
93
|
end
|
@@ -54,11 +54,56 @@ module Stretchy
|
|
54
54
|
#
|
55
55
|
# @see https://www.elastic.co/guide/en/elasticsearch/guide/current/proximity-relevance.html Elasticsearch guide: proximity for relevance
|
56
56
|
def fulltext(params = {})
|
57
|
-
add_params(params
|
57
|
+
add_params(params)
|
58
58
|
add_params(params, should: true, slop: FULLTEXT_SLOP)
|
59
59
|
self
|
60
60
|
end
|
61
61
|
|
62
|
+
#
|
63
|
+
# Adds a MoreLikeThis query to the chain. Pass in document ids,
|
64
|
+
# an array of index/name/ids, or a string to get documents that
|
65
|
+
# have similar terms.
|
66
|
+
#
|
67
|
+
# This method accepts all the options in the Elasticsearch
|
68
|
+
# `more_like_this` query, which are pretty extensive. See the
|
69
|
+
# documentation (link below) to get an idea of what is available.
|
70
|
+
#
|
71
|
+
# Only one of `:docs`, `:ids`, or `:like_text` is required, and
|
72
|
+
# one of those three must be present.
|
73
|
+
#
|
74
|
+
# @param params = {} [Hash] Params used to build the `more_like_this` query
|
75
|
+
# @option params [Array] :like_text A string to compare documents do
|
76
|
+
# @option params [Array] :ids A list of document ids to compare documents to
|
77
|
+
# @option params [Array] :docs An array of document hashes. You can pass the
|
78
|
+
# results of another query here, or a hash with fields '_index', '_type'
|
79
|
+
# and '_id'
|
80
|
+
# @option params [Array] :fields A list of fields to use in the comparison.
|
81
|
+
# Defaults to '_all'
|
82
|
+
# @option params [Array] :include Whether the source documents should be
|
83
|
+
# included in the result set. Defaults to `false`
|
84
|
+
#
|
85
|
+
# @return [MatchClause] allows continuing the query chain
|
86
|
+
#
|
87
|
+
# @example Getting more like a document by id
|
88
|
+
# query.more_like(ids: other_result_id)
|
89
|
+
#
|
90
|
+
# @example Getting more like a document from another query
|
91
|
+
# query.more_like(docs: other_query.results)
|
92
|
+
#
|
93
|
+
# @example Getting more like a document from a string
|
94
|
+
# query.more_like(like_text: 'puppies and kittens are great')
|
95
|
+
#
|
96
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-mlt-query.html Elasticsearch more-like-this query documentation
|
97
|
+
#
|
98
|
+
def more_like(params = {}, options = {})
|
99
|
+
query = Queries::MoreLikeThisQuery.new(params)
|
100
|
+
options[:inverse] = true if inverse?
|
101
|
+
options[:should] = true if should?
|
102
|
+
|
103
|
+
base.add_query(query, options)
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
62
107
|
#
|
63
108
|
# Switches to inverted context. Matches applied here work the same way as
|
64
109
|
# {#initialize}, but returned documents must **not** match these filters.
|
@@ -22,8 +22,8 @@ module Stretchy
|
|
22
22
|
|
23
23
|
def to_search
|
24
24
|
json = {}
|
25
|
-
json[:query] = @query.to_search if
|
26
|
-
json[:filter] = @filter.to_search if
|
25
|
+
json[:query] = @query.to_search if query
|
26
|
+
json[:filter] = @filter.to_search if filter
|
27
27
|
{ filtered: json }
|
28
28
|
end
|
29
29
|
end
|
@@ -16,13 +16,13 @@ module Stretchy
|
|
16
16
|
attribute :max, Float
|
17
17
|
|
18
18
|
validations do
|
19
|
-
rule :field,
|
19
|
+
rule :field, field: { required: true }
|
20
20
|
rule :string, type: String
|
21
21
|
rule :string, :required
|
22
22
|
rule :operator, inclusion: {in: OPERATORS}
|
23
23
|
rule :type, inclusion: {in: MATCH_TYPES}
|
24
24
|
rule :slop, type: Numeric
|
25
|
-
rule :min,
|
25
|
+
rule :min, :min_should_match
|
26
26
|
rule :max, type: Numeric
|
27
27
|
end
|
28
28
|
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Stretchy
|
2
|
+
module Queries
|
3
|
+
class MoreLikeThisQuery < Base
|
4
|
+
|
5
|
+
attribute :fields, Array[String]
|
6
|
+
attribute :like_text, String
|
7
|
+
attribute :ids, Array[Integer]
|
8
|
+
attribute :docs, Array
|
9
|
+
attribute :max_query_terms, Integer
|
10
|
+
attribute :min_term_freq, Integer
|
11
|
+
attribute :min_doc_freq, Integer
|
12
|
+
attribute :max_doc_freq, Integer
|
13
|
+
attribute :min_word_length, Integer
|
14
|
+
attribute :max_word_length, Integer
|
15
|
+
attribute :stop_words, Array[String]
|
16
|
+
attribute :analyzer, String
|
17
|
+
attribute :boost_terms, Integer
|
18
|
+
attribute :include, Axiom::Types::Boolean
|
19
|
+
attribute :boost, Float
|
20
|
+
|
21
|
+
validations do
|
22
|
+
rule :fields, field: { array: true }
|
23
|
+
end
|
24
|
+
|
25
|
+
def after_initialize(params = {})
|
26
|
+
if params[:docs]
|
27
|
+
@docs = coerce_docs(Array(params[:docs]))
|
28
|
+
end
|
29
|
+
|
30
|
+
require_one!(:like_text, :docs, :ids)
|
31
|
+
end
|
32
|
+
|
33
|
+
def coerce_docs(docs)
|
34
|
+
docs.map do |doc|
|
35
|
+
coerced = {
|
36
|
+
'_index' => doc['_index'] || doc[:_index],
|
37
|
+
'_type' => doc['_type'] || doc[:_type],
|
38
|
+
}
|
39
|
+
|
40
|
+
source = doc[:doc] || doc['']
|
41
|
+
if source
|
42
|
+
coerced['doc'] = source
|
43
|
+
else
|
44
|
+
coerced['_id'] = doc['_id'] || doc[:_id]
|
45
|
+
end
|
46
|
+
coerced
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_search
|
51
|
+
{
|
52
|
+
more_like_this: json_attributes
|
53
|
+
}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/stretchy/queries.rb
CHANGED
data/lib/stretchy/version.rb
CHANGED
data/lib/stretchy_validations.rb
CHANGED
@@ -3,6 +3,8 @@ require 'validation/rule/not_empty'
|
|
3
3
|
require 'validation/rule/regular_expression'
|
4
4
|
|
5
5
|
# custom for Stretchy
|
6
|
+
require 'validation/rule/stretchy_rule'
|
7
|
+
require 'validation/rule/min_should_match'
|
6
8
|
require 'validation/rule/required'
|
7
9
|
require 'validation/rule/responds_to'
|
8
10
|
require 'validation/rule/decay'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Validation
|
2
2
|
module Rule
|
3
|
-
class Decay
|
3
|
+
class Decay < StretchyRule
|
4
4
|
DECAY_FUNCTIONS = [:gauss, :linear, :exp]
|
5
5
|
|
6
6
|
def error_key
|
@@ -10,11 +10,6 @@ module Validation
|
|
10
10
|
def valid_value?(value)
|
11
11
|
DECAY_FUNCTIONS.any?{|f| f == value || f.to_s == value }
|
12
12
|
end
|
13
|
-
|
14
|
-
def params
|
15
|
-
{}
|
16
|
-
end
|
17
|
-
|
18
13
|
end
|
19
14
|
end
|
20
15
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Validation
|
2
2
|
module Rule
|
3
|
-
class Distance
|
3
|
+
class Distance < StretchyRule
|
4
4
|
DISTANCE_FORMAT = /^(\d+)(km|mi)$/
|
5
5
|
|
6
6
|
def error_key
|
@@ -10,11 +10,6 @@ module Validation
|
|
10
10
|
def valid_value?(value)
|
11
11
|
!!(value.to_s =~ DISTANCE_FORMAT)
|
12
12
|
end
|
13
|
-
|
14
|
-
def params
|
15
|
-
{}
|
16
|
-
end
|
17
|
-
|
18
13
|
end
|
19
14
|
end
|
20
15
|
end
|
@@ -1,22 +1,23 @@
|
|
1
1
|
module Validation
|
2
2
|
module Rule
|
3
|
-
class Field
|
3
|
+
class Field < StretchyRule
|
4
4
|
|
5
5
|
def error_key
|
6
6
|
:field
|
7
7
|
end
|
8
8
|
|
9
9
|
def valid_value?(value)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
return true if empty_ok?(value)
|
11
|
+
if params[:array]
|
12
|
+
value.all? {|v| valid_class?(v) && !is_empty?(v) }
|
13
|
+
else
|
14
|
+
valid_class?(value) && !is_empty?(value)
|
15
|
+
end
|
14
16
|
end
|
15
17
|
|
16
|
-
def
|
17
|
-
{}
|
18
|
+
def valid_class?(value)
|
19
|
+
[String, Symbol, Numeric].any?{|c| value.is_a?(c) }
|
18
20
|
end
|
19
|
-
|
20
21
|
end
|
21
22
|
end
|
22
23
|
end
|
@@ -1,17 +1,13 @@
|
|
1
1
|
module Validation
|
2
2
|
module Rule
|
3
|
-
class Inclusion
|
4
|
-
|
5
|
-
def initialize(params = {})
|
6
|
-
@params = params
|
7
|
-
end
|
3
|
+
class Inclusion < StretchyRule
|
8
4
|
|
9
5
|
def error_key
|
10
6
|
:inclusion
|
11
7
|
end
|
12
8
|
|
13
9
|
def valid_value?(value)
|
14
|
-
return true if value
|
10
|
+
return true if empty_ok?(value)
|
15
11
|
within.any? do |allowed_value|
|
16
12
|
if value.respond_to?(:eql?)
|
17
13
|
value.eql?(allowed_value)
|
@@ -22,11 +18,7 @@ module Validation
|
|
22
18
|
end
|
23
19
|
|
24
20
|
def within
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
def params
|
29
|
-
@params
|
21
|
+
params[:in] || params[:within]
|
30
22
|
end
|
31
23
|
end
|
32
24
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Validation
|
2
2
|
module Rule
|
3
|
-
class Latitude
|
3
|
+
class Latitude < StretchyRule
|
4
4
|
|
5
5
|
def error_key
|
6
6
|
:latitude
|
@@ -12,10 +12,6 @@ module Validation
|
|
12
12
|
valid = false unless value && value.to_f <= 90 && value.to_f >= -90
|
13
13
|
valid
|
14
14
|
end
|
15
|
-
|
16
|
-
def params
|
17
|
-
{}
|
18
|
-
end
|
19
15
|
end
|
20
16
|
end
|
21
17
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Validation
|
2
2
|
module Rule
|
3
|
-
class Longitude
|
3
|
+
class Longitude < StretchyRule
|
4
4
|
|
5
5
|
def error_key
|
6
6
|
:longitude
|
@@ -12,11 +12,6 @@ module Validation
|
|
12
12
|
valid = false unless value && value <= 180 && value >= -180
|
13
13
|
valid
|
14
14
|
end
|
15
|
-
|
16
|
-
def params
|
17
|
-
{}
|
18
|
-
end
|
19
|
-
|
20
15
|
end
|
21
16
|
end
|
22
17
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Validation
|
2
|
+
module Rule
|
3
|
+
class MinShouldMatch < StretchyRule
|
4
|
+
|
5
|
+
FORMAT_REGEX = /^-?\d+([<>]-?\d+)?%?$/
|
6
|
+
|
7
|
+
def error_key
|
8
|
+
:field
|
9
|
+
end
|
10
|
+
|
11
|
+
def valid_value?(value)
|
12
|
+
return true if empty_ok?(value)
|
13
|
+
value.to_s =~ FORMAT_REGEX
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,26 +1,14 @@
|
|
1
1
|
module Validation
|
2
2
|
module Rule
|
3
|
-
class Required
|
3
|
+
class Required < StretchyRule
|
4
4
|
|
5
5
|
def error_key
|
6
6
|
:required
|
7
7
|
end
|
8
8
|
|
9
9
|
def valid_value?(value)
|
10
|
-
|
11
|
-
when nil
|
12
|
-
false
|
13
|
-
when String, Array, Hash
|
14
|
-
!value.empty?
|
15
|
-
else
|
16
|
-
true
|
17
|
-
end
|
10
|
+
!is_empty?(value)
|
18
11
|
end
|
19
|
-
|
20
|
-
def params
|
21
|
-
{}
|
22
|
-
end
|
23
|
-
|
24
12
|
end
|
25
13
|
end
|
26
14
|
end
|
@@ -1,10 +1,6 @@
|
|
1
1
|
module Validation
|
2
2
|
module Rule
|
3
|
-
class RespondsTo
|
4
|
-
|
5
|
-
def initialize(params)
|
6
|
-
@params = params
|
7
|
-
end
|
3
|
+
class RespondsTo < StretchyRule
|
8
4
|
|
9
5
|
def error_key
|
10
6
|
:responds_to
|
@@ -13,11 +9,6 @@ module Validation
|
|
13
9
|
def valid_value?(value)
|
14
10
|
value.respond_to?(params[:method])
|
15
11
|
end
|
16
|
-
|
17
|
-
def params
|
18
|
-
@params
|
19
|
-
end
|
20
|
-
|
21
12
|
end
|
22
13
|
end
|
23
14
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Validation
|
2
|
+
module Rule
|
3
|
+
class StretchyRule
|
4
|
+
|
5
|
+
def initialize(params = {})
|
6
|
+
@params = params
|
7
|
+
end
|
8
|
+
|
9
|
+
def error_key
|
10
|
+
raise "Override in subclass"
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid_value?(value)
|
14
|
+
raise "Override in subclass"
|
15
|
+
end
|
16
|
+
|
17
|
+
def empty_ok?(value)
|
18
|
+
!required? && is_empty?(value)
|
19
|
+
end
|
20
|
+
|
21
|
+
def invalid_empty?(value)
|
22
|
+
required? && is_empty?(value)
|
23
|
+
end
|
24
|
+
|
25
|
+
def is_empty?(value)
|
26
|
+
value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
27
|
+
end
|
28
|
+
|
29
|
+
def required?
|
30
|
+
!!(params.is_a?(Hash) && params[:required])
|
31
|
+
end
|
32
|
+
|
33
|
+
def params
|
34
|
+
@params
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/validation/rule/type.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
module Validation
|
2
2
|
module Rule
|
3
|
-
class Type
|
3
|
+
class Type < StretchyRule
|
4
4
|
|
5
5
|
def initialize(params = {})
|
6
6
|
if params.is_a?(Hash)
|
7
7
|
@params = params
|
8
|
+
@params[:classes] = Array(params[:classes])
|
8
9
|
else
|
9
|
-
@params = { classes: params }
|
10
|
+
@params = { classes: Array(params) }
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
@@ -16,29 +17,15 @@ module Validation
|
|
16
17
|
|
17
18
|
def valid_value?(value)
|
18
19
|
return true if value.nil? && !params[:required]
|
19
|
-
|
20
|
-
valid = true
|
21
20
|
if params[:array]
|
22
|
-
|
21
|
+
value.all? {|v| valid_type?(v) }
|
23
22
|
else
|
24
|
-
|
23
|
+
valid_type?(value)
|
25
24
|
end
|
26
|
-
valid
|
27
25
|
end
|
28
26
|
|
29
|
-
def
|
30
|
-
|
31
|
-
case params[:classes]
|
32
|
-
when Array
|
33
|
-
valid = false unless params[:classes].any? {|type| value.is_a?(type) }
|
34
|
-
else
|
35
|
-
valid = false unless value.is_a?(params[:classes])
|
36
|
-
end
|
37
|
-
valid
|
38
|
-
end
|
39
|
-
|
40
|
-
def params
|
41
|
-
@params
|
27
|
+
def valid_type?(value)
|
28
|
+
params[:classes].any? {|type| value.is_a?(type) }
|
42
29
|
end
|
43
30
|
end
|
44
31
|
end
|
data/solano.yml
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stretchy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- agius
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: elasticsearch
|
@@ -173,7 +173,6 @@ extra_rdoc_files: []
|
|
173
173
|
files:
|
174
174
|
- ".gitignore"
|
175
175
|
- ".ruby-version"
|
176
|
-
- ".travis.yml"
|
177
176
|
- ".yardopts"
|
178
177
|
- Gemfile
|
179
178
|
- README.md
|
@@ -222,6 +221,7 @@ files:
|
|
222
221
|
- lib/stretchy/queries/function_score_query.rb
|
223
222
|
- lib/stretchy/queries/match_all_query.rb
|
224
223
|
- lib/stretchy/queries/match_query.rb
|
224
|
+
- lib/stretchy/queries/more_like_this_query.rb
|
225
225
|
- lib/stretchy/results.rb
|
226
226
|
- lib/stretchy/results/base.rb
|
227
227
|
- lib/stretchy/results/null_results.rb
|
@@ -244,10 +244,12 @@ files:
|
|
244
244
|
- lib/validation/rule/inclusion.rb
|
245
245
|
- lib/validation/rule/latitude.rb
|
246
246
|
- lib/validation/rule/longitude.rb
|
247
|
-
- lib/validation/rule/
|
247
|
+
- lib/validation/rule/min_should_match.rb
|
248
248
|
- lib/validation/rule/required.rb
|
249
249
|
- lib/validation/rule/responds_to.rb
|
250
|
+
- lib/validation/rule/stretchy_rule.rb
|
250
251
|
- lib/validation/rule/type.rb
|
252
|
+
- solano.yml
|
251
253
|
- stretchy.gemspec
|
252
254
|
homepage: https://github.com/hired/stretchy
|
253
255
|
licenses:
|
data/.travis.yml
DELETED