search_redux 0.0.4 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 05db95b0f1118f55c5e23b538d535fd045c1f423
4
- data.tar.gz: 37ecb95b3b84d3e6654561f917529c8f7455aed7
2
+ SHA256:
3
+ metadata.gz: 2e38a9e09ad47bb9223780ed4b5abe6f6dba9c1d3436e79942fa92b82787e241
4
+ data.tar.gz: 0caf36ef1c0d6cdd2acadc8e2edefebf3c3264f644d4c8960ccacd5c51e5de6d
5
5
  SHA512:
6
- metadata.gz: f83575ea4ced7d460ab58edd6ab1a2651e586e48d717da44ad1af4a7af3b5048646cb436e2295f6a5017a2012773f29a59f49464d814e35ea62825142c40d578
7
- data.tar.gz: bf3d3f9024b2e449e73125da20cd223df7478201008d6ed98691f4304285a9717f8b852c7b464bd93d57efc766e5018223c14d9d2c6df28da160071927ce6054
6
+ metadata.gz: 28b3fdad95a054363fd2608a845f70c0a4f2d11b55b8e97fa5f747bc5f70b5e81f386e434b07cecad761c7560c1fcfbf52de60bcb8eed49fbaf1abf40dfed2db
7
+ data.tar.gz: 7cf80dae2a11c2497451ce5e1170b0884a623a854c40c9b84ab35d6f8569d77822c457297d2cf31acbef35e2ba2f9d6321f000bf37f154cd64c4cbbf96df6f6e
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
- *.gem
2
- *.swp
1
+ *.gem
2
+ *.swp
3
+ *.lock
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile CHANGED
@@ -1,3 +1,9 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'factory_girl'
7
+ gem 'rspec'
8
+ gem 'guard-rspec'
9
+ end
data/Guardfile ADDED
@@ -0,0 +1,11 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :rspec do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
10
+ end
11
+
data/README.md CHANGED
@@ -1,27 +1,46 @@
1
- # Full text search redux
2
-
3
- The current version is just a code extract of a simple text search logic using Postgres [functionality](http://www.postgresql.org/docs/8.3/static/textsearch.html) and a simple fallback for other RDBMs (e.g. Mysql)
4
-
5
- For now the usage is limited, it expects a `title` and a `content` column.
6
-
7
- ## Installation
8
-
9
- Include the gem in your Gemfile:
10
-
11
- ```ruby
12
- gem 'search_redux'
13
- ```
14
-
15
- ## Quick start
16
-
17
- ```ruby
18
- class MyModel
19
- act_as_searchable
20
- end
21
-
22
- class MyController
23
- def index
24
- an_article = MyModel.text_search 'query phrase'
25
- end
26
- end
27
- ```
1
+ # Search redux
2
+
3
+ A simple way to add full text search to your Rails models. Currently supported RDBMs are [Postgres](http://www.postgresql.org/docs/8.3/static/textsearch.html) anda simple fallback for other RDBMs (e.g. Mysql).
4
+
5
+ ## Requirements
6
+
7
+ Search redux requires at least Ruby >= 1.9.2 and Rails >= 3.0.0 and Postgres >= 9.2.
8
+
9
+ ## Installation
10
+
11
+ Include the gem in your Gemfile:
12
+
13
+ ```ruby
14
+ gem 'search_redux'
15
+ ```
16
+
17
+ ## Quick start
18
+
19
+ In your model call the `act_as_searchable` with the columns that you want to search and the column for rank-based ordering.
20
+
21
+ ```ruby
22
+ class MyModel
23
+ act_as_searchable :columns => %w(title content), :rank => 'title'
24
+ end
25
+ ```
26
+
27
+ You can easily search via the `text_search` method.
28
+
29
+ ```ruby
30
+ class MyController
31
+ def index
32
+ an_article = MyModel.text_search 'query phrase'
33
+ end
34
+ end
35
+ ```
36
+
37
+ ## License (MIT)
38
+
39
+ Copyright (c) 2022 Marian Posaceanu
40
+
41
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
42
+
43
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
44
+
45
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
46
+
@@ -1,9 +1,9 @@
1
- module SearchRedux
2
- class Error < StandardError; end
3
-
4
- module Errors
5
- class ActAsSearchableUnintialized < SearchRedux::Error; end
6
-
7
- class NoQuery < SearchRedux::Error; end
8
- end
9
- end
1
+ module SearchRedux
2
+ class Error < StandardError; end
3
+
4
+ module Errors
5
+ class ActAsSearchableUnintialized < SearchRedux::Error; end
6
+
7
+ class NoQuery < SearchRedux::Error; end
8
+ end
9
+ end
@@ -1,7 +1,7 @@
1
- module SearchRedux
2
- module Glue
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
6
- end
7
- end
1
+ module SearchRedux
2
+ module Glue
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+ end
7
+ end
@@ -1,16 +1,16 @@
1
- module SearchRedux
2
- module Helpers
3
- def select_best_query_strategy(adapter, query)
4
- case adapter
5
- when /mysql.*/i
6
- SearchRedux::Mysql.compatible_search(query)
7
- when /postgres.*/i
8
- SearchRedux::Postgres.compatible_search(query)
9
- end
10
- end
11
-
12
- def db_adapter
13
- ActiveRecord::Base::connection.adapter_name
14
- end
15
- end
16
- end
1
+ module SearchRedux
2
+ module Helpers
3
+ def select_best_query_strategy(adapter, query)
4
+ case adapter
5
+ when /mysql.*/i
6
+ SearchRedux::Mysql.compatible_search(query)
7
+ when /postgres.*/i
8
+ SearchRedux::Postgres.compatible_search(query)
9
+ end
10
+ end
11
+
12
+ def db_adapter
13
+ ActiveRecord::Base::connection.adapter_name
14
+ end
15
+ end
16
+ end
@@ -1,20 +1,17 @@
1
- module SearchRedux
2
- require 'rails'
3
-
4
- class Railtie < Rails::Railtie
5
- initializer 'search_redux.insert_into_active_record' do |app|
6
- SearchRedux::Railtie.insert
7
- end
8
-
9
- # rake_tasks { load 'tasks/search_redux.rake' }
10
- end
11
-
12
- class Railtie
13
- def self.insert
14
- if defined? ActiveRecord
15
- # do the dew
16
- ActiveRecord::Base.send(:include, SearchRedux::Glue)
17
- end
18
- end
19
- end
20
- end
1
+ module SearchRedux
2
+ require 'rails'
3
+
4
+ class Railtie < Rails::Railtie
5
+ initializer 'search_redux.insert_into_active_record' do |app|
6
+ SearchRedux::Railtie.insert
7
+ end
8
+ end
9
+
10
+ class Railtie
11
+ def self.insert
12
+ if defined? ActiveRecord
13
+ ActiveRecord::Base.send(:include, SearchRedux::Glue)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,7 +1,7 @@
1
- module SearchRedux
2
- class Mysql
3
- def self.compatible_search(query)
4
- ->(obj) { obj.where("title like :q or content like :q", q: "%#{query}%") }
5
- end
6
- end
7
- end
1
+ module SearchRedux
2
+ class Mysql
3
+ def self.compatible_search(query)
4
+ ->(obj) { obj.where("title like :q or content like :q", q: "%#{query}%") }
5
+ end
6
+ end
7
+ end
@@ -1,30 +1,31 @@
1
- module SearchRedux
2
- class Postgres
3
- class << self
4
- attr_accessor :sanitized_query
5
-
6
- def compatible_search(options)
7
- query = options[:query]
8
-
9
- rank_query = rank_sql options[:rank], query
10
- search_query = search_sql options[:columns]
11
-
12
- ->(obj) { obj.where(search_query, q: query).order(rank_query) }
13
- end
14
-
15
- def rank_sql(rank_column, query)
16
- sanitized_query = ActionController::Base.helpers.sanitize(query)
17
-
18
- "ts_rank(to_tsvector(#{rank_column}), plainto_tsquery('#{sanitized_query}')) desc"
19
- end
20
-
21
- def search_sql(columns)
22
- template = ->(column_name) {
23
- return "to_tsvector('english', #{column_name}) @@ plainto_tsquery(:q)"
24
- }
25
-
26
- columns.map { |c| template.call(c) }.join(' OR ')
27
- end
28
- end
29
- end
30
- end
1
+ module SearchRedux
2
+ class Postgres
3
+ class << self
4
+ attr_accessor :sanitized_query
5
+
6
+ def compatible_search(options)
7
+ query = to_ts_query(options[:query])
8
+ rank_query = rank_sql(options[:rank], query)
9
+ search_query = search_sql(options[:columns])
10
+
11
+ ->(obj) { obj.where(Arel.sql(search_query), q: Arel.sql(query)).order(Arel.sql(rank_query)) }
12
+ end
13
+
14
+ def to_ts_query(query)
15
+ query.split.map { |ts| "#{ts}:*" }.join(" & ")
16
+ end
17
+
18
+ def rank_sql(rank_column, query)
19
+ "ts_rank(to_tsvector(#{rank_column}), to_tsquery('#{query}')) desc"
20
+ end
21
+
22
+ def search_sql(columns)
23
+ template = ->(column_name) {
24
+ return "to_tsvector('english', #{column_name}) @@ to_tsquery(:q)"
25
+ }
26
+
27
+ columns.map { |c| template.call(c) }.join(' OR ')
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,35 +1,35 @@
1
- module SearchRedux
2
- extend Helpers
3
-
4
- class Searchable
5
- attr_accessor :columns
6
- attr_accessor :rank
7
- attr_reader :options
8
-
9
- def self.default_options
10
- @default_options ||= {
11
- :columns => %w(title content),
12
- :rank => 'title'
13
- }
14
- end
15
-
16
- def initialize(options = {})
17
- options = self.class.default_options.merge(options)
18
-
19
- @options = options
20
- end
21
-
22
- def full_text_search(query, active_record_instance)
23
- if query.present?
24
- @options.merge! :query => query
25
-
26
- adapter = SearchRedux.db_adapter
27
- strategy = SearchRedux.select_best_query_strategy(adapter, @options)
28
-
29
- strategy.call(active_record_instance)
30
- else
31
- active_record_instance.scoped
32
- end
33
- end
34
- end
35
- end
1
+ module SearchRedux
2
+ extend Helpers
3
+
4
+ class Searchable
5
+ attr_accessor :columns
6
+ attr_accessor :rank
7
+ attr_reader :options
8
+
9
+ def self.default_options
10
+ @default_options ||= {
11
+ :columns => %w(title content),
12
+ :rank => 'title'
13
+ }
14
+ end
15
+
16
+ def initialize(options = {})
17
+ options = self.class.default_options.merge(options)
18
+
19
+ @options = options
20
+ end
21
+
22
+ def full_text_search(query, active_record_instance)
23
+ if query.present?
24
+ @options.merge! :query => query
25
+
26
+ adapter = SearchRedux.db_adapter
27
+ strategy = SearchRedux.select_best_query_strategy(adapter, @options)
28
+
29
+ strategy.call(active_record_instance)
30
+ else
31
+ active_record_instance.scoped
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,3 +1,3 @@
1
- module SearchRedux
2
- VERSION = '0.0.4' unless defined? SearchRedux::VERSION
3
- end
1
+ module SearchRedux
2
+ VERSION = '1.0.2' unless defined? SearchRedux::VERSION
3
+ end
data/lib/search_redux.rb CHANGED
@@ -1,27 +1,27 @@
1
- require 'search_redux/version'
2
- require 'search_redux/errors'
3
- require 'search_redux/helpers'
4
- require 'search_redux/glue'
5
- require 'search_redux/searchable'
6
- require 'search_redux/rdbms/mysql'
7
- require 'search_redux/rdbms/postgres'
8
-
9
- require 'search_redux/railtie'
10
-
11
- module SearchRedux
12
- extend Helpers
13
-
14
- module ClassMethods
15
- def act_as_searchable(options = {})
16
- attr_accessor :searchable
17
-
18
- @searchable = SearchRedux::Searchable.new options
19
- end
20
-
21
- def text_search(query)
22
- raise(Errors::ActAsSearchableUnintialized, 'Use act_as_searchable') unless @searchable
23
-
24
- @searchable.full_text_search(query, self)
25
- end
26
- end
27
- end
1
+ require 'search_redux/version'
2
+ require 'search_redux/errors'
3
+ require 'search_redux/helpers'
4
+ require 'search_redux/glue'
5
+ require 'search_redux/searchable'
6
+ require 'search_redux/rdbms/mysql'
7
+ require 'search_redux/rdbms/postgres'
8
+
9
+ require 'search_redux/railtie'
10
+
11
+ module SearchRedux
12
+ extend Helpers
13
+
14
+ module ClassMethods
15
+ def act_as_searchable(options = {})
16
+ attr_accessor :searchable
17
+
18
+ @searchable = SearchRedux::Searchable.new options
19
+ end
20
+
21
+ def text_search(query)
22
+ raise(Errors::ActAsSearchableUnintialized, 'Use act_as_searchable') unless @searchable
23
+
24
+ @searchable.full_text_search(query, self)
25
+ end
26
+ end
27
+ end
data/search_redux.gemspec CHANGED
@@ -1,22 +1,23 @@
1
- $LOAD_PATH.push File.expand_path("../lib", __FILE__)
2
- require 'search_redux/version'
3
-
4
- Gem::Specification.new do |s|
5
- s.name = 'search_redux'
6
- s.version = SearchRedux::VERSION
7
- s.platform = Gem::Platform::RUBY
8
- s.summary = 'Add a text_search method to your models.'
9
- s.description = 'Simple ActiveRecord full text search.'
10
- s.author = 'Marian Posaceanu'
11
- s.email = 'contact@marianposaceanu.com'
12
- s.files = `git ls-files`.split("\n")
13
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
- s.require_paths = ['lib']
15
- s.homepage = 'https://github.com/dakull/search_redux'
16
-
17
- s.required_ruby_version = '>= 1.9.2'
18
-
19
- s.add_dependency('activerecord', '>= 3.0.0')
20
- s.add_dependency('activemodel', '>= 3.0.0')
21
- s.add_dependency('activesupport', '>= 3.0.0')
22
- end
1
+ $LOAD_PATH.push File.expand_path("../lib", __FILE__)
2
+ require 'search_redux/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'search_redux'
6
+ s.version = SearchRedux::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.licenses = ['MIT']
9
+ s.summary = 'Add a text_search method to your models.'
10
+ s.description = 'Simple ActiveRecord full text search.'
11
+ s.author = 'Marian Posaceanu'
12
+ s.email = 'contact@marianposaceanu.com'
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.require_paths = ['lib']
16
+ s.homepage = 'https://github.com/dakull/search_redux'
17
+
18
+ s.required_ruby_version = '>= 1.9.2'
19
+
20
+ s.add_runtime_dependency 'activerecord', '>= 5.0.0'
21
+ s.add_runtime_dependency 'activemodel', '>= 5.0.0'
22
+ s.add_runtime_dependency 'activesupport', '>= 5.0.0'
23
+ end
@@ -0,0 +1,17 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+
12
+ # Run specs in random order to surface order dependencies. If you find an
13
+ # order dependency and want to debug it, you can fix the order by providing
14
+ # the seed, which is printed after each run.
15
+ # --seed 1234
16
+ config.order = 'random'
17
+ end
metadata CHANGED
@@ -1,65 +1,67 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: search_redux
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marian Posaceanu
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-19 00:00:00.000000000 Z
11
+ date: 2023-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 3.0.0
19
+ version: 5.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 3.0.0
26
+ version: 5.0.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activemodel
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 3.0.0
33
+ version: 5.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 3.0.0
40
+ version: 5.0.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 3.0.0
47
+ version: 5.0.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 3.0.0
54
+ version: 5.0.0
55
55
  description: Simple ActiveRecord full text search.
56
56
  email: contact@marianposaceanu.com
57
57
  executables: []
58
58
  extensions: []
59
59
  extra_rdoc_files: []
60
60
  files:
61
- - .gitignore
61
+ - ".gitignore"
62
+ - ".rspec"
62
63
  - Gemfile
64
+ - Guardfile
63
65
  - README.md
64
66
  - lib/search_redux.rb
65
67
  - lib/search_redux/errors.rb
@@ -71,27 +73,29 @@ files:
71
73
  - lib/search_redux/searchable.rb
72
74
  - lib/search_redux/version.rb
73
75
  - search_redux.gemspec
76
+ - spec/spec_helper.rb
74
77
  homepage: https://github.com/dakull/search_redux
75
- licenses: []
78
+ licenses:
79
+ - MIT
76
80
  metadata: {}
77
- post_install_message:
81
+ post_install_message:
78
82
  rdoc_options: []
79
83
  require_paths:
80
84
  - lib
81
85
  required_ruby_version: !ruby/object:Gem::Requirement
82
86
  requirements:
83
- - - '>='
87
+ - - ">="
84
88
  - !ruby/object:Gem::Version
85
89
  version: 1.9.2
86
90
  required_rubygems_version: !ruby/object:Gem::Requirement
87
91
  requirements:
88
- - - '>='
92
+ - - ">="
89
93
  - !ruby/object:Gem::Version
90
94
  version: '0'
91
95
  requirements: []
92
- rubyforge_project:
93
- rubygems_version: 2.0.0
94
- signing_key:
96
+ rubygems_version: 3.3.7
97
+ signing_key:
95
98
  specification_version: 4
96
99
  summary: Add a text_search method to your models.
97
- test_files: []
100
+ test_files:
101
+ - spec/spec_helper.rb