pg_search 0.7.4 → 0.7.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 60b69d6e0600c725eba8d5f820eb05439982824a
4
- data.tar.gz: d1f90c57f0d2db953516b2edf99127b0326be044
3
+ metadata.gz: 56abc4100a0dcd75ed558ec0ec631d53088ab5bf
4
+ data.tar.gz: 33edaaa054f61e59efa18c8e96f0ecd9cc12630c
5
5
  SHA512:
6
- metadata.gz: 6157156f723baccc67229b771852de1adf1d21ffa5bc41e4a593908453c7af7125e1ae79ba46a0fa91de593e01c3b3117858e284c2e70b0cb9c7b4dd48184a27
7
- data.tar.gz: 60a6c495d334f7af8dc4f98f9c20637de6058c218b1e35d98e1d298d923fa4bf6199ec456b8c6a5c1ab357d6c44e4b40348e16a99b92a03063dd8931fc4fa4d4
6
+ metadata.gz: d4e3fb0b2571d4fec4f447f1f6df9108b70e6219c7381e9d79e95d559bb063389a4ded5f50db1c320a1564647a83a9050ba6dfb32f3b87adae9866028c7633b8
7
+ data.tar.gz: f618f99de2af02e89346f6cde00036e6c56b88292511b434140276d470b6033da2717ebc132b5364e4ba9bdf32afc29ed6811098c532916db6973154b0db0d9e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # pg_search changelog
2
2
 
3
+ ## 0.7.5
4
+
5
+ * Add option to make feature available only for sorting. (Brent Wheeldon)
6
+
3
7
  ## 0.7.4
4
8
 
5
9
  * Fix which STI class name is used for searchable_type for PgSearch::Document. (Ewan McDougall)
data/README.md CHANGED
@@ -1,17 +1,10 @@
1
- # pg_search
1
+ # [pg_search](http://github.com/Casecommons/pg_search/)
2
2
 
3
- http://github.com/Casecommons/pg_search/
4
-
5
- [<img src="https://secure.travis-ci.org/Casecommons/pg_search.png?branch=master"
6
- alt="Build Status" />](http://travis-ci.org/Casecommons/pg_search)
7
- [<img src="https://gemnasium.com/Casecommons/pg_search.png" alt="Dependency Status"
8
- />](https://gemnasium.com/Casecommons/pg_search)
9
- [<img src="https://codeclimate.com/github/Casecommons/pg_search.png"
10
- />](https://codeclimate.com/github/Casecommons/pg_search)
11
- [<img src="https://coveralls.io/repos/Casecommons/pg_search/badge.png?branch=master"
12
- alt="Coverage Status" />](https://coveralls.io/r/Casecommons/pg_search)
13
- [<img src="https://badge.fury.io/rb/pg_search.png" alt="Gem Version"
14
- />](http://badge.fury.io/rb/pg_search)
3
+ [![Build Status](https://secure.travis-ci.org/Casecommons/pg_search.svg?branch=master)](https://travis-ci.org/Casecommons/pg_search)
4
+ [![Code Climate](https://img.shields.io/codeclimate/github/Casecommons/pg_search.svg)](https://codeclimate.com/github/Casecommons/pg_search)
5
+ [![Coverage Status](https://img.shields.io/coveralls/Casecommons/pg_search/master.svg)](https://coveralls.io/r/Casecommons/pg_search)
6
+ [![Gem Version](https://badge.fury.io/rb/pg_search.svg)](https://rubygems.org/gems/pg_search)
7
+ [![Dependency Status](https://gemnasium.com/Casecommons/pg_search.svg)](https://gemnasium.com/Casecommons/pg_search)
15
8
 
16
9
  ## DESCRIPTION
17
10
 
@@ -670,6 +663,30 @@ Number.search_any_word('one two three') # => [one, two, three]
670
663
  Number.search_all_words('one two three') # => []
671
664
  ```
672
665
 
666
+ ##### :sort_only
667
+
668
+ Setting this attribute to true will make this feature available for sorting,
669
+ but will not include it in the query's WHERE condition.
670
+
671
+ ```ruby
672
+ class Person < ActiveRecord::Base
673
+ include PgSearch
674
+ pg_search_scope :search,
675
+ :against => :name,
676
+ :using => {
677
+ :tsearch => {:any_word => true}
678
+ :dmetaphone => {:any_word => true, :sort_only => true}
679
+ }
680
+ end
681
+
682
+ exact = Person.create!(:name => 'ash hines')
683
+ one_exact_one_close = Person.create!(:name => 'ash heinz')
684
+ one_exact = Person.create!(:name => 'ash smith')
685
+ one_close = Person.create!(:name => 'leigh heinz')
686
+
687
+ Person.search('ash hines') # => [exact, one_exact_one_close, one_exact]
688
+ ```
689
+
673
690
  #### :dmetaphone (Double Metaphone soundalike search)
674
691
 
675
692
  [Double Metaphone](http://en.wikipedia.org/wiki/Double_Metaphone) is an
@@ -1,12 +1,14 @@
1
- require "logger"
1
+ require 'logger'
2
2
 
3
3
  module PgSearch
4
4
  class Document < ActiveRecord::Base
5
5
  include PgSearch
6
+
6
7
  self.table_name = 'pg_search_documents'
7
8
  belongs_to :searchable, :polymorphic => true
8
9
 
9
- before_validation :update_content
10
+ before_validation :update_content,
11
+ :unless => Proc.new { |doc| doc.searchable.nil? }
10
12
 
11
13
  # The logger might not have loaded yet.
12
14
  # https://github.com/Casecommons/pg_search/issues/26
@@ -54,25 +54,8 @@ module PgSearch
54
54
  end
55
55
 
56
56
  def tsdocument
57
- tsdocument_terms = []
58
-
59
- columns_to_use = options[:tsvector_column] ?
60
- columns.select { |c| c.is_a?(PgSearch::Configuration::ForeignColumn) } :
61
- columns
62
-
63
- if columns_to_use.present?
64
- tsdocument_terms << columns_to_use.map do |search_column|
65
- tsvector = Arel::Nodes::NamedFunction.new(
66
- "to_tsvector",
67
- [dictionary, Arel.sql(normalize(search_column.to_sql))]
68
- ).to_sql
69
-
70
- if search_column.weight.nil?
71
- tsvector
72
- else
73
- "setweight(#{tsvector}, #{connection.quote(search_column.weight)})"
74
- end
75
- end.join(" || ")
57
+ tsdocument_terms = (columns_to_use || []).map do |search_column|
58
+ column_to_tsvector(search_column)
76
59
  end
77
60
 
78
61
  if options[:tsvector_column]
@@ -107,6 +90,27 @@ module PgSearch
107
90
  def arel_wrap(sql_string)
108
91
  Arel::Nodes::Grouping.new(Arel.sql(sql_string))
109
92
  end
93
+
94
+ def columns_to_use
95
+ if options[:tsvector_column]
96
+ columns.select { |c| c.is_a?(PgSearch::Configuration::ForeignColumn) }
97
+ else
98
+ columns
99
+ end
100
+ end
101
+
102
+ def column_to_tsvector(search_column)
103
+ tsvector = Arel::Nodes::NamedFunction.new(
104
+ "to_tsvector",
105
+ [dictionary, Arel.sql(normalize(search_column.to_sql))]
106
+ ).to_sql
107
+
108
+ if search_column.weight.nil?
109
+ tsvector
110
+ else
111
+ "setweight(#{tsvector}, #{connection.quote(search_column.weight)})"
112
+ end
113
+ end
110
114
  end
111
115
  end
112
116
  end
@@ -1,22 +1,10 @@
1
- require "rails/generators/base"
1
+ require 'pg_search/migration/generator'
2
2
 
3
3
  module PgSearch
4
4
  module Migration
5
- class AssociatedAgainstGenerator < Rails::Generators::Base
6
- source_root File.expand_path("../templates", __FILE__)
7
-
8
- def create_migration
9
- now = Time.now.utc
10
- filename = "#{now.strftime('%Y%m%d%H%M%S')}_add_pg_search_associated_against_support_functions.rb"
11
- template "add_pg_search_associated_against_support_functions.rb.erb", "db/migrate/#{filename}"
12
- end
13
-
14
- private
15
-
16
- def read_sql_file(filename)
17
- sql_directory = File.expand_path("../../../../sql", __FILE__)
18
- source_path = File.join(sql_directory, "#{filename}.sql")
19
- File.read(source_path)
5
+ class AssociatedAgainstGenerator < Generator
6
+ def migration_name
7
+ 'add_pg_search_associated_against_support_functions'.freeze
20
8
  end
21
9
  end
22
10
  end
@@ -1,22 +1,10 @@
1
- require "rails/generators/base"
1
+ require 'pg_search/migration/generator'
2
2
 
3
3
  module PgSearch
4
4
  module Migration
5
- class DmetaphoneGenerator < Rails::Generators::Base
6
- source_root File.expand_path("../templates", __FILE__)
7
-
8
- def create_migration
9
- now = Time.now.utc
10
- filename = "#{now.strftime('%Y%m%d%H%M%S')}_add_pg_search_dmetaphone_support_functions.rb"
11
- template "add_pg_search_dmetaphone_support_functions.rb.erb", "db/migrate/#{filename}"
12
- end
13
-
14
- private
15
-
16
- def read_sql_file(filename)
17
- sql_directory = File.expand_path("../../../../sql", __FILE__)
18
- source_path = File.join(sql_directory, "#{filename}.sql")
19
- File.read(source_path)
5
+ class DmetaphoneGenerator < Generator
6
+ def migration_name
7
+ 'add_pg_search_dmetaphone_support_functions'.freeze
20
8
  end
21
9
  end
22
10
  end
@@ -0,0 +1,28 @@
1
+ require 'rails/generators/base'
2
+
3
+ module PgSearch
4
+ module Migration
5
+ class Generator < Rails::Generators::Base
6
+ hide!
7
+
8
+ def self.inherited(subclass)
9
+ super
10
+ subclass.source_root File.expand_path('../templates', __FILE__)
11
+ end
12
+
13
+ def create_migration
14
+ now = Time.now.utc
15
+ filename = "#{now.strftime('%Y%m%d%H%M%S')}_#{migration_name}.rb"
16
+ template "#{migration_name}.rb.erb", "db/migrate/#{filename}"
17
+ end
18
+
19
+ private
20
+
21
+ def read_sql_file(filename)
22
+ sql_directory = File.expand_path('../../../../sql', __FILE__)
23
+ source_path = File.join(sql_directory, "#{filename}.sql")
24
+ File.read(source_path).strip
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,14 +1,10 @@
1
- require "rails/generators/base"
1
+ require 'pg_search/migration/generator'
2
2
 
3
3
  module PgSearch
4
4
  module Migration
5
- class MultisearchGenerator < Rails::Generators::Base
6
- source_root Pathname.new(File.dirname(__FILE__)).join("templates")
7
-
8
- def create_migration
9
- now = Time.now.utc
10
- filename = "#{now.strftime('%Y%m%d%H%M%S')}_create_pg_search_documents.rb"
11
- copy_file "create_pg_search_documents.rb", "db/migrate/#{filename}"
5
+ class MultisearchGenerator < Generator
6
+ def migration_name
7
+ 'create_pg_search_documents'
12
8
  end
13
9
  end
14
10
  end
@@ -3,7 +3,7 @@ class AddPgSearchAssociatedAgainstSupportFunctions < ActiveRecord::Migration
3
3
  say_with_time("Adding support functions for pg_search :associated_against") do
4
4
  if ActiveRecord::Base.connection.send(:postgresql_version) < 80400
5
5
  execute <<-'SQL'
6
- <%= read_sql_file "array_agg" %>
6
+ <%= read_sql_file "array_agg" %>
7
7
  SQL
8
8
  end
9
9
  end
@@ -13,7 +13,7 @@ class AddPgSearchAssociatedAgainstSupportFunctions < ActiveRecord::Migration
13
13
  say_with_time("Dropping support functions for pg_search :associated_against") do
14
14
  if ActiveRecord::Base.connection.send(:postgresql_version) < 80400
15
15
  execute <<-'SQL'
16
- <%= read_sql_file "uninstall_array_agg" %>
16
+ <%= read_sql_file "uninstall_array_agg" %>
17
17
  SQL
18
18
  end
19
19
  end
@@ -33,7 +33,9 @@ module PgSearch
33
33
  delegate :connection, :quoted_table_name, :to => :@model
34
34
 
35
35
  def conditions
36
- config.features.map do |feature_name, feature_options|
36
+ config.features.reject do |feature_name, feature_options|
37
+ feature_options && feature_options[:sort_only]
38
+ end.map do |feature_name, feature_options|
37
39
  feature_for(feature_name).conditions
38
40
  end.inject do |accumulator, expression|
39
41
  Arel::Nodes::Or.new(accumulator, expression)
@@ -1,3 +1,3 @@
1
1
  module PgSearch
2
- VERSION = "0.7.4".freeze
2
+ VERSION = "0.7.5".freeze
3
3
  end
data/pg_search.gemspec CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
24
24
 
25
25
  s.add_development_dependency 'rake'
26
26
  s.add_development_dependency 'pry'
27
- s.add_development_dependency 'rspec', '>= 2.14'
27
+ s.add_development_dependency 'rspec', '~> 3.0'
28
28
  s.add_development_dependency 'with_model'
29
29
 
30
30
  s.required_ruby_version = ">= 1.9.2"
@@ -34,8 +34,8 @@ describe PgSearch do
34
34
  ]
35
35
 
36
36
  results = ModelWithoutAgainst.with_another('abcdef')
37
- results.map(&:title).should =~ included.map(&:title)
38
- results.should_not include(excluded)
37
+ expect(results.map(&:title)).to match_array(included.map(&:title))
38
+ expect(results).not_to include(excluded)
39
39
  end
40
40
  end
41
41
 
@@ -70,8 +70,8 @@ describe PgSearch do
70
70
  :another_model => AssociatedModel.create!(:title => 'stuvwx'))
71
71
 
72
72
  results = ModelWithBelongsTo.with_associated('abcdef')
73
- results.map(&:title).should =~ included.map(&:title)
74
- results.should_not include(excluded)
73
+ expect(results.map(&:title)).to match_array(included.map(&:title))
74
+ expect(results).not_to include(excluded)
75
75
  end
76
76
  end
77
77
 
@@ -113,8 +113,8 @@ describe PgSearch do
113
113
  ])
114
114
 
115
115
  results = ModelWithHasMany.with_associated('foo bar')
116
- results.map(&:title).should =~ included.map(&:title)
117
- results.should_not include(excluded)
116
+ expect(results.map(&:title)).to match_array(included.map(&:title))
117
+ expect(results).not_to include(excluded)
118
118
  end
119
119
 
120
120
  it "uses an unscoped relation of the assocated model" do
@@ -129,8 +129,8 @@ describe PgSearch do
129
129
  ]
130
130
 
131
131
  results = ModelWithHasMany.limit(1).order("id ASC").with_associated('foo bar')
132
- results.map(&:title).should =~ included.map(&:title)
133
- results.should_not include(excluded)
132
+ expect(results.map(&:title)).to match_array(included.map(&:title))
133
+ expect(results).not_to include(excluded)
134
134
  end
135
135
 
136
136
  end
@@ -192,8 +192,8 @@ describe PgSearch do
192
192
  ]
193
193
 
194
194
  results = ModelWithManyAssociations.with_associated('foo bar')
195
- results.map(&:title).should =~ included.map(&:title)
196
- excluded.each { |object| results.should_not include(object) }
195
+ expect(results.map(&:title)).to match_array(included.map(&:title))
196
+ excluded.each { |object| expect(results).not_to include(object) }
197
197
  end
198
198
  end
199
199
 
@@ -247,8 +247,8 @@ describe PgSearch do
247
247
  ]
248
248
 
249
249
  results = ModelWithDoubleAssociation.with_associated('foo bar')
250
- results.map(&:title).should =~ included.map(&:title)
251
- excluded.each { |object| results.should_not include(object) }
250
+ expect(results.map(&:title)).to match_array(included.map(&:title))
251
+ excluded.each { |object| expect(results).not_to include(object) }
252
252
  end
253
253
  end
254
254
  end
@@ -300,9 +300,9 @@ describe PgSearch do
300
300
 
301
301
  results = ModelWithAssociation.with_associated('foo bar')
302
302
 
303
- results.to_sql.scan("INNER JOIN").length.should == 1
304
- included.each { |object| results.should include(object) }
305
- excluded.each { |object| results.should_not include(object) }
303
+ expect(results.to_sql.scan("INNER JOIN").length).to eq(1)
304
+ included.each { |object| expect(results).to include(object) }
305
+ excluded.each { |object| expect(results).not_to include(object) }
306
306
  end
307
307
 
308
308
  end
@@ -339,8 +339,8 @@ describe PgSearch do
339
339
  ]
340
340
 
341
341
  results = Model.with_associated('123')
342
- results.map(&:number).should =~ included.map(&:number)
343
- results.should_not include(excluded)
342
+ expect(results.map(&:number)).to match_array(included.map(&:number))
343
+ expect(results).not_to include(excluded)
344
344
  end
345
345
  end
346
346
 
@@ -375,8 +375,8 @@ describe PgSearch do
375
375
  results = Parent.search_name('bar.foo').includes(:children)
376
376
  results.to_a
377
377
 
378
- results.should include(included)
379
- results.should_not include(excluded)
378
+ expect(results).to include(included)
379
+ expect(results).not_to include(excluded)
380
380
  end
381
381
  end
382
382
  end
@@ -422,8 +422,8 @@ describe PgSearch do
422
422
 
423
423
  results = ModelWithAssociation.joins(:associated_models).merge(relation)
424
424
 
425
- results.should include(*included)
426
- results.should_not include(*excluded)
425
+ expect(results).to include(*included)
426
+ expect(results).not_to include(*excluded)
427
427
  end
428
428
  end
429
429
 
@@ -463,8 +463,8 @@ describe PgSearch do
463
463
 
464
464
  results = company.positions.search('teller 1')
465
465
 
466
- results.should include(*included)
467
- results.should_not include(*excluded)
466
+ expect(results).to include(*included)
467
+ expect(results).not_to include(*excluded)
468
468
  end
469
469
  end
470
470
 
@@ -505,8 +505,8 @@ describe PgSearch do
505
505
 
506
506
  results = company.positions.search('teller 1')
507
507
 
508
- results.should include(*included)
509
- results.should_not include(*excluded)
508
+ expect(results).to include(*included)
509
+ expect(results).not_to include(*excluded)
510
510
  end
511
511
  end
512
512
  end
@@ -23,8 +23,8 @@ describe "pagination" do
23
23
  best = PaginatedModel.create!(:name => "foo foo foo")
24
24
  good = PaginatedModel.create!(:name => "foo bar bar")
25
25
 
26
- PaginatedModel.page(1).search_name("foo").should == [best, better]
27
- PaginatedModel.page(2).search_name("foo").should == [good]
26
+ expect(PaginatedModel.page(1).search_name("foo")).to eq([best, better])
27
+ expect(PaginatedModel.page(2).search_name("foo")).to eq([good])
28
28
  end
29
29
 
30
30
  it "is chainable after a search scope" do
@@ -32,8 +32,8 @@ describe "pagination" do
32
32
  best = PaginatedModel.create!(:name => "foo foo foo")
33
33
  good = PaginatedModel.create!(:name => "foo bar bar")
34
34
 
35
- PaginatedModel.search_name("foo").page(1).should == [best, better]
36
- PaginatedModel.search_name("foo").page(2).should == [good]
35
+ expect(PaginatedModel.search_name("foo").page(1)).to eq([best, better])
36
+ expect(PaginatedModel.search_name("foo").page(2)).to eq([good])
37
37
  end
38
38
  end
39
39
  end