search_redux 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 05db95b0f1118f55c5e23b538d535fd045c1f423
4
+ data.tar.gz: 37ecb95b3b84d3e6654561f917529c8f7455aed7
5
+ SHA512:
6
+ metadata.gz: f83575ea4ced7d460ab58edd6ab1a2651e586e48d717da44ad1af4a7af3b5048646cb436e2295f6a5017a2012773f29a59f49464d814e35ea62825142c40d578
7
+ data.tar.gz: bf3d3f9024b2e449e73125da20cd223df7478201008d6ed98691f4304285a9717f8b852c7b464bd93d57efc766e5018223c14d9d2c6df28da160071927ce6054
@@ -0,0 +1,2 @@
1
+ *.gem
2
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,27 @@
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
+ ```
@@ -0,0 +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
@@ -0,0 +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
@@ -0,0 +1,7 @@
1
+ module SearchRedux
2
+ module Glue
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+ end
7
+ end
@@ -0,0 +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
@@ -0,0 +1,20 @@
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
@@ -0,0 +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
@@ -0,0 +1,30 @@
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
@@ -0,0 +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
@@ -0,0 +1,3 @@
1
+ module SearchRedux
2
+ VERSION = '0.0.4' unless defined? SearchRedux::VERSION
3
+ end
@@ -0,0 +1,22 @@
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
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: search_redux
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Marian Posaceanu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-05-19 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: 3.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 3.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: activemodel
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 3.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 3.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: 3.0.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 3.0.0
55
+ description: Simple ActiveRecord full text search.
56
+ email: contact@marianposaceanu.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - .gitignore
62
+ - Gemfile
63
+ - README.md
64
+ - lib/search_redux.rb
65
+ - lib/search_redux/errors.rb
66
+ - lib/search_redux/glue.rb
67
+ - lib/search_redux/helpers.rb
68
+ - lib/search_redux/railtie.rb
69
+ - lib/search_redux/rdbms/mysql.rb
70
+ - lib/search_redux/rdbms/postgres.rb
71
+ - lib/search_redux/searchable.rb
72
+ - lib/search_redux/version.rb
73
+ - search_redux.gemspec
74
+ homepage: https://github.com/dakull/search_redux
75
+ licenses: []
76
+ metadata: {}
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - '>='
84
+ - !ruby/object:Gem::Version
85
+ version: 1.9.2
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 2.0.0
94
+ signing_key:
95
+ specification_version: 4
96
+ summary: Add a text_search method to your models.
97
+ test_files: []