searchable-by 0.5.0
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 +7 -0
- data/.gitignore +4 -0
- data/.rubocop.yml +10 -0
- data/.travis.yml +8 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +77 -0
- data/LICENSE +13 -0
- data/README.md +42 -0
- data/Rakefile +9 -0
- data/lib/searchable-by.rb +1 -0
- data/lib/searchable_by.rb +111 -0
- data/searchable-by.gemspec +25 -0
- data/spec/searchable_by_spec.rb +42 -0
- data/spec/spec_helper.rb +54 -0
- metadata +170 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: '008edf75bb0e4b27410f7e889cbfd26eda27d0391dd7e70be3e984a962ddd756'
|
|
4
|
+
data.tar.gz: 9b2fbbc4cc13b2cfe6e23998616ec48e49617bfb67db3143f800c5d35134b2df
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 0fa58611207ecef62a12c698be927aa34659e0b19f5c5a4ce6c8c2c87b77df49349fb72a4356683f406a80110727442e854448f4b1dc20bc04527e1981af03a2
|
|
7
|
+
data.tar.gz: b9dbbde8350310301567ed1ba6cf8a45d80813e7f99415a6e0a6dc6d1a69b4dbd0f340a39851b8db4e291b503f21c2f4f9e8d74311cdaa5fe705a3a06a9201e1
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
searchable-by (0.5.0)
|
|
5
|
+
activerecord
|
|
6
|
+
activesupport
|
|
7
|
+
|
|
8
|
+
GEM
|
|
9
|
+
remote: http://rubygems.org/
|
|
10
|
+
specs:
|
|
11
|
+
activemodel (5.2.3)
|
|
12
|
+
activesupport (= 5.2.3)
|
|
13
|
+
activerecord (5.2.3)
|
|
14
|
+
activemodel (= 5.2.3)
|
|
15
|
+
activesupport (= 5.2.3)
|
|
16
|
+
arel (>= 9.0)
|
|
17
|
+
activesupport (5.2.3)
|
|
18
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
19
|
+
i18n (>= 0.7, < 2)
|
|
20
|
+
minitest (~> 5.1)
|
|
21
|
+
tzinfo (~> 1.1)
|
|
22
|
+
arel (9.0.0)
|
|
23
|
+
ast (2.4.0)
|
|
24
|
+
concurrent-ruby (1.1.5)
|
|
25
|
+
diff-lcs (1.3)
|
|
26
|
+
i18n (1.6.0)
|
|
27
|
+
concurrent-ruby (~> 1.0)
|
|
28
|
+
jaro_winkler (1.5.2)
|
|
29
|
+
minitest (5.11.3)
|
|
30
|
+
parallel (1.17.0)
|
|
31
|
+
parser (2.6.3.0)
|
|
32
|
+
ast (~> 2.4.0)
|
|
33
|
+
rainbow (3.0.0)
|
|
34
|
+
rake (12.3.2)
|
|
35
|
+
rspec (3.8.0)
|
|
36
|
+
rspec-core (~> 3.8.0)
|
|
37
|
+
rspec-expectations (~> 3.8.0)
|
|
38
|
+
rspec-mocks (~> 3.8.0)
|
|
39
|
+
rspec-core (3.8.0)
|
|
40
|
+
rspec-support (~> 3.8.0)
|
|
41
|
+
rspec-expectations (3.8.3)
|
|
42
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
43
|
+
rspec-support (~> 3.8.0)
|
|
44
|
+
rspec-mocks (3.8.0)
|
|
45
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
46
|
+
rspec-support (~> 3.8.0)
|
|
47
|
+
rspec-support (3.8.0)
|
|
48
|
+
rubocop (0.68.1)
|
|
49
|
+
jaro_winkler (~> 1.5.1)
|
|
50
|
+
parallel (~> 1.10)
|
|
51
|
+
parser (>= 2.5, != 2.5.1.1)
|
|
52
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
53
|
+
ruby-progressbar (~> 1.7)
|
|
54
|
+
unicode-display_width (>= 1.4.0, < 1.6)
|
|
55
|
+
rubocop-performance (1.2.0)
|
|
56
|
+
rubocop (>= 0.68.0)
|
|
57
|
+
ruby-progressbar (1.10.0)
|
|
58
|
+
sqlite3 (1.4.1)
|
|
59
|
+
thread_safe (0.3.6)
|
|
60
|
+
tzinfo (1.2.5)
|
|
61
|
+
thread_safe (~> 0.1)
|
|
62
|
+
unicode-display_width (1.5.0)
|
|
63
|
+
|
|
64
|
+
PLATFORMS
|
|
65
|
+
ruby
|
|
66
|
+
|
|
67
|
+
DEPENDENCIES
|
|
68
|
+
bundler
|
|
69
|
+
rake
|
|
70
|
+
rspec
|
|
71
|
+
rubocop
|
|
72
|
+
rubocop-performance
|
|
73
|
+
searchable-by!
|
|
74
|
+
sqlite3
|
|
75
|
+
|
|
76
|
+
BUNDLED WITH
|
|
77
|
+
2.0.1
|
data/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2019 Black Square Media Ltd
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Searchable By
|
|
2
|
+
|
|
3
|
+
ActiveRecord plugin to quickly create search scopes.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add `gem 'searchable-by'` to your Gemfile.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
class Post < ActiveRecord::Base
|
|
13
|
+
belongs_to :author
|
|
14
|
+
|
|
15
|
+
# Limit the number of terms per query to 3.
|
|
16
|
+
searchable_by max_terms: 3 do
|
|
17
|
+
# Allow to search strings.
|
|
18
|
+
column :title
|
|
19
|
+
|
|
20
|
+
# ... and integers.
|
|
21
|
+
column :id, type: :integer
|
|
22
|
+
|
|
23
|
+
# Allow custom arel nodes.
|
|
24
|
+
column { Author.arel_table[:name] }
|
|
25
|
+
column { Arel::Nodes::NamedFunction.new('CONCAT', [arel_table[:prefix], arel_table[:suffix]]) }
|
|
26
|
+
|
|
27
|
+
# Support custom scopes.
|
|
28
|
+
scope do
|
|
29
|
+
joins(:author)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Search for 'alice'
|
|
35
|
+
Post.search_by('alice') # => ActiveRecord::Relation
|
|
36
|
+
|
|
37
|
+
# Search for 'alice' AND 'pie recipe'
|
|
38
|
+
Post.search_by('alice "pie recipe"')
|
|
39
|
+
|
|
40
|
+
# Search for 'alice' but NOT for 'pie recipe'
|
|
41
|
+
Post.search_by('alice -"pie recipe"')
|
|
42
|
+
```
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'searchable_by'
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
require 'active_record'
|
|
2
|
+
require 'shellwords'
|
|
3
|
+
|
|
4
|
+
module ActiveRecord
|
|
5
|
+
module SearchableBy
|
|
6
|
+
class Config < Hash
|
|
7
|
+
def initialize
|
|
8
|
+
update columns: [], max_terms: 5
|
|
9
|
+
scope { all }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def column(*attrs, &block)
|
|
13
|
+
opts = attrs.extract_options!
|
|
14
|
+
cols = self[:columns]
|
|
15
|
+
attrs.each do |attr|
|
|
16
|
+
cols.push(opts.merge(column: attr))
|
|
17
|
+
end
|
|
18
|
+
cols.push(opts.merge(column: block)) if block
|
|
19
|
+
cols
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def scope(&block)
|
|
23
|
+
self[:scope] = block
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.norm_values(query)
|
|
28
|
+
values = Shellwords.split(query.to_s)
|
|
29
|
+
values.flatten!
|
|
30
|
+
values.reject!(&:blank?)
|
|
31
|
+
values.uniq!
|
|
32
|
+
values
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.build_clauses(relations, values)
|
|
36
|
+
clauses = values.map do |value|
|
|
37
|
+
negate = value[0] == '-'
|
|
38
|
+
value.slice!(0) if negate || value[0] == '+'
|
|
39
|
+
|
|
40
|
+
c0, *cn = relations.map do |opts|
|
|
41
|
+
build_condition(opts, value)
|
|
42
|
+
end.compact
|
|
43
|
+
next unless c0
|
|
44
|
+
|
|
45
|
+
[cn.inject(c0) {|x, part| x.or(part) }, negate]
|
|
46
|
+
end
|
|
47
|
+
clauses.compact!
|
|
48
|
+
clauses
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.build_condition(opts, value)
|
|
52
|
+
case opts[:type]
|
|
53
|
+
when :int, :integer
|
|
54
|
+
begin
|
|
55
|
+
opts[:rel].eq(Integer(value))
|
|
56
|
+
rescue ArgumentError
|
|
57
|
+
nil
|
|
58
|
+
end
|
|
59
|
+
else
|
|
60
|
+
value = value.dup
|
|
61
|
+
value.gsub!('%', '\%')
|
|
62
|
+
value.gsub!('_', '\_')
|
|
63
|
+
opts[:rel].matches("%#{value}%")
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
module ClassMethods
|
|
68
|
+
def self.extended(base) # :nodoc:
|
|
69
|
+
base.class_attribute :_searchable_by_config, instance_accessor: false, instance_predicate: false
|
|
70
|
+
base._searchable_by_config = Config.new
|
|
71
|
+
super
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def inherited(base) # :nodoc:
|
|
75
|
+
base._searchable_by_config = _searchable_by_config.deep_dup
|
|
76
|
+
super
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def searchable_by(max_terms: 5, &block)
|
|
80
|
+
_searchable_by_config.instance_eval(&block)
|
|
81
|
+
_searchable_by_config[:max_terms] = max_terms if max_terms
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @param [String] query the search query
|
|
85
|
+
# @return [ActiveRecord::Relation] the scoped relation
|
|
86
|
+
def search_by(query)
|
|
87
|
+
columns = _searchable_by_config[:columns]
|
|
88
|
+
return all if columns.empty?
|
|
89
|
+
|
|
90
|
+
values = SearchableBy.norm_values(query).first(_searchable_by_config[:max_terms])
|
|
91
|
+
return all if values.empty?
|
|
92
|
+
|
|
93
|
+
relations = columns.map do |opts|
|
|
94
|
+
rel = opts[:column].is_a?(Proc) ? opts[:column].call : arel_table[opts[:column]]
|
|
95
|
+
opts.merge(rel: rel)
|
|
96
|
+
end
|
|
97
|
+
clauses = SearchableBy.build_clauses(relations, values)
|
|
98
|
+
return all if clauses.empty?
|
|
99
|
+
|
|
100
|
+
scope = instance_exec(&_searchable_by_config[:scope])
|
|
101
|
+
clauses.inject(scope) do |x, (clause, negate)|
|
|
102
|
+
negate ? x.where.not(clause) : x.where(clause)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
class Base
|
|
109
|
+
extend SearchableBy::ClassMethods
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
Gem::Specification.new do |s|
|
|
2
|
+
s.name = 'searchable-by'
|
|
3
|
+
s.version = '0.5.0'
|
|
4
|
+
s.authors = ['Dimitrij Denissenko']
|
|
5
|
+
s.email = ['dimitrij@blacksquaremedia.com']
|
|
6
|
+
s.summary = 'Generate search scopes'
|
|
7
|
+
s.description = 'ActiveRecord plugin'
|
|
8
|
+
s.homepage = 'https://github.com/bsm/sortable-by'
|
|
9
|
+
s.license = 'MIT'
|
|
10
|
+
|
|
11
|
+
s.files = `git ls-files -z`.split("\x0").reject {|f| f.match(%r{^spec/}) }
|
|
12
|
+
s.test_files = `git ls-files -z -- spec/*`.split("\x0")
|
|
13
|
+
s.require_paths = ['lib']
|
|
14
|
+
s.required_ruby_version = '>= 2.4'
|
|
15
|
+
|
|
16
|
+
s.add_dependency 'activerecord'
|
|
17
|
+
s.add_dependency 'activesupport'
|
|
18
|
+
|
|
19
|
+
s.add_development_dependency 'bundler'
|
|
20
|
+
s.add_development_dependency 'rake'
|
|
21
|
+
s.add_development_dependency 'rspec'
|
|
22
|
+
s.add_development_dependency 'rubocop'
|
|
23
|
+
s.add_development_dependency 'rubocop-performance'
|
|
24
|
+
s.add_development_dependency 'sqlite3'
|
|
25
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ActiveRecord::SearchableBy do
|
|
4
|
+
it 'should ignore bad inputs' do
|
|
5
|
+
expect(Post.search_by(nil).count).to eq(4)
|
|
6
|
+
expect(Post.search_by('').count).to eq(4)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'should generate SQL' do
|
|
10
|
+
sql = Post.search_by('123').to_sql
|
|
11
|
+
expect(sql).to include(%("posts"."id" = 123))
|
|
12
|
+
expect(sql).to include(%("posts"."title" LIKE '%123%'))
|
|
13
|
+
|
|
14
|
+
sql = Post.search_by('foo%bar').to_sql
|
|
15
|
+
expect(sql).not_to include(%("posts"."id"))
|
|
16
|
+
expect(sql).to include(%("posts"."title" LIKE '%foo\\%bar%'))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'should search' do
|
|
20
|
+
expect(Post.search_by('ALICE').pluck(:title)).to match_array(%w[titla title])
|
|
21
|
+
expect(Post.search_by('bOb').pluck(:title)).to match_array(%w[titlo titlu])
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'should search across multiple words' do
|
|
25
|
+
expect(Post.search_by('ALICE title').pluck(:title)).to match_array(%w[title])
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'should support search markers' do
|
|
29
|
+
expect(Post.search_by('aLiCe -title').pluck(:title)).to match_array(%w[titla])
|
|
30
|
+
expect(Post.search_by('+alice "pie recipe"').pluck(:title)).to match_array(%w[title])
|
|
31
|
+
expect(Post.search_by('bob -"piu recipe"').pluck(:title)).to match_array(%w[titlo])
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'should search within scopes' do
|
|
35
|
+
expect(Post.where(title: 'title').search_by('ALICE').pluck(:title)).to match_array(%w[title])
|
|
36
|
+
expect(Post.where(title: 'title').search_by('bOb').pluck(:title)).to match_array(%w[])
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'should search integers' do
|
|
40
|
+
expect(Post.search_by(POSTS[:alice1].id.to_s).count).to eq(1)
|
|
41
|
+
end
|
|
42
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
ENV['RACK_ENV'] ||= 'test'
|
|
2
|
+
require 'searchable-by'
|
|
3
|
+
require 'rspec'
|
|
4
|
+
|
|
5
|
+
ActiveRecord::Base.configurations['test'] = { 'adapter' => 'sqlite3', 'database' => ':memory:' }
|
|
6
|
+
ActiveRecord::Base.establish_connection :test
|
|
7
|
+
|
|
8
|
+
ActiveRecord::Base.connection.instance_eval do
|
|
9
|
+
create_table :authors do |t|
|
|
10
|
+
t.string :name
|
|
11
|
+
end
|
|
12
|
+
create_table :posts do |t|
|
|
13
|
+
t.integer :author_id, null: false
|
|
14
|
+
t.string :title
|
|
15
|
+
t.text :body
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class AbstractModel < ActiveRecord::Base
|
|
20
|
+
self.abstract_class = true
|
|
21
|
+
|
|
22
|
+
searchable_by do
|
|
23
|
+
column :id, type: :integer
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class Author < AbstractModel
|
|
28
|
+
has_many :posts
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class Post < AbstractModel
|
|
32
|
+
belongs_to :author
|
|
33
|
+
|
|
34
|
+
searchable_by do
|
|
35
|
+
column :title, :body
|
|
36
|
+
column { Author.arel_table[:name] }
|
|
37
|
+
|
|
38
|
+
scope do
|
|
39
|
+
joins(:author)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
AUTHORS = {
|
|
45
|
+
alice: Author.create!(name: 'Alice'),
|
|
46
|
+
bob: Author.create!(name: 'Bob'),
|
|
47
|
+
}.freeze
|
|
48
|
+
|
|
49
|
+
POSTS = {
|
|
50
|
+
alice1: AUTHORS[:alice].posts.create!(title: 'titla', body: 'my pia recipe '),
|
|
51
|
+
alice2: AUTHORS[:alice].posts.create!(title: 'title', body: 'your pie recipe'),
|
|
52
|
+
bob1: AUTHORS[:bob].posts.create!(title: 'titlo', body: 'her pio recipe'),
|
|
53
|
+
bob2: AUTHORS[:bob].posts.create!(title: 'titlu', body: 'our piu recipe'),
|
|
54
|
+
}.freeze
|
metadata
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: searchable-by
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.5.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Dimitrij Denissenko
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2019-05-10 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: activerecord
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: activesupport
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: bundler
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rake
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rspec
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rubocop
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: rubocop-performance
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: sqlite3
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - ">="
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '0'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - ">="
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0'
|
|
125
|
+
description: ActiveRecord plugin
|
|
126
|
+
email:
|
|
127
|
+
- dimitrij@blacksquaremedia.com
|
|
128
|
+
executables: []
|
|
129
|
+
extensions: []
|
|
130
|
+
extra_rdoc_files: []
|
|
131
|
+
files:
|
|
132
|
+
- ".gitignore"
|
|
133
|
+
- ".rubocop.yml"
|
|
134
|
+
- ".travis.yml"
|
|
135
|
+
- Gemfile
|
|
136
|
+
- Gemfile.lock
|
|
137
|
+
- LICENSE
|
|
138
|
+
- README.md
|
|
139
|
+
- Rakefile
|
|
140
|
+
- lib/searchable-by.rb
|
|
141
|
+
- lib/searchable_by.rb
|
|
142
|
+
- searchable-by.gemspec
|
|
143
|
+
- spec/searchable_by_spec.rb
|
|
144
|
+
- spec/spec_helper.rb
|
|
145
|
+
homepage: https://github.com/bsm/sortable-by
|
|
146
|
+
licenses:
|
|
147
|
+
- MIT
|
|
148
|
+
metadata: {}
|
|
149
|
+
post_install_message:
|
|
150
|
+
rdoc_options: []
|
|
151
|
+
require_paths:
|
|
152
|
+
- lib
|
|
153
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
154
|
+
requirements:
|
|
155
|
+
- - ">="
|
|
156
|
+
- !ruby/object:Gem::Version
|
|
157
|
+
version: '2.4'
|
|
158
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
159
|
+
requirements:
|
|
160
|
+
- - ">="
|
|
161
|
+
- !ruby/object:Gem::Version
|
|
162
|
+
version: '0'
|
|
163
|
+
requirements: []
|
|
164
|
+
rubygems_version: 3.0.3
|
|
165
|
+
signing_key:
|
|
166
|
+
specification_version: 4
|
|
167
|
+
summary: Generate search scopes
|
|
168
|
+
test_files:
|
|
169
|
+
- spec/searchable_by_spec.rb
|
|
170
|
+
- spec/spec_helper.rb
|