textacular 3.0.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.
- data/CHANGELOG.md +164 -0
- data/Gemfile +3 -0
- data/README.md +143 -0
- data/Rakefile +154 -0
- data/lib/textacular.rb +227 -0
- data/lib/textacular/full_text_indexer.rb +79 -0
- data/lib/textacular/postgres_module_installer.rb +57 -0
- data/lib/textacular/rails.rb +10 -0
- data/lib/textacular/searchable.rb +20 -0
- data/lib/textacular/tasks.rb +18 -0
- data/lib/textacular/version.rb +7 -0
- data/spec/config.yml.example +4 -0
- data/spec/fixtures/character.rb +0 -0
- data/spec/fixtures/game.rb +9 -0
- data/spec/fixtures/webcomic.rb +9 -0
- data/spec/spec_helper.rb +78 -0
- data/spec/textacular/searchable_spec.rb +92 -0
- data/spec/textacular_spec.rb +216 -0
- metadata +178 -0
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'textacular'
|
5
|
+
require 'shoulda'
|
6
|
+
require 'pry'
|
7
|
+
require 'active_record'
|
8
|
+
require 'textacular'
|
9
|
+
require 'textacular/searchable'
|
10
|
+
|
11
|
+
config = YAML.load_file File.expand_path(File.dirname(__FILE__) + '/config.yml')
|
12
|
+
ActiveRecord::Base.establish_connection config.merge(:adapter => :postgresql)
|
13
|
+
|
14
|
+
class ARStandIn < ActiveRecord::Base;
|
15
|
+
self.abstract_class = true
|
16
|
+
extend Textacular
|
17
|
+
end
|
18
|
+
|
19
|
+
class NotThere < ARStandIn; end
|
20
|
+
|
21
|
+
class TextacularWebComic < ARStandIn;
|
22
|
+
has_many :characters, :foreign_key => :web_comic_id
|
23
|
+
self.table_name = :web_comics
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
class WebComic < ActiveRecord::Base
|
28
|
+
# string :name
|
29
|
+
# string :author
|
30
|
+
# integer :id
|
31
|
+
|
32
|
+
has_many :characters
|
33
|
+
end
|
34
|
+
|
35
|
+
class WebComicWithSearchable < WebComic
|
36
|
+
extend Searchable
|
37
|
+
end
|
38
|
+
|
39
|
+
class WebComicWithSearchableName < WebComic
|
40
|
+
extend Searchable(:name)
|
41
|
+
end
|
42
|
+
|
43
|
+
class WebComicWithSearchableNameAndAuthor < WebComic
|
44
|
+
extend Searchable(:name, :author)
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
class Character < ActiveRecord::Base
|
49
|
+
# string :name
|
50
|
+
# string :description
|
51
|
+
# integer :web_comic_id
|
52
|
+
|
53
|
+
belongs_to :web_comic
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
class Game < ActiveRecord::Base
|
58
|
+
# string :system
|
59
|
+
# string :title
|
60
|
+
# text :description
|
61
|
+
end
|
62
|
+
|
63
|
+
class GameExtendedWithTextacular < Game
|
64
|
+
extend Textacular
|
65
|
+
end
|
66
|
+
|
67
|
+
class GameExtendedWithTextacularAndCustomLanguage < GameExtendedWithTextacular
|
68
|
+
def searchable_language
|
69
|
+
'spanish'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
class GameFail < Game; end
|
75
|
+
|
76
|
+
class GameFailExtendedWithTextacular < GameFail
|
77
|
+
extend Textacular
|
78
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'textacular/searchable'
|
3
|
+
|
4
|
+
class SearchableTest < Test::Unit::TestCase
|
5
|
+
context "when extending an ActiveRecord::Base subclass" do
|
6
|
+
context "with no parameters" do
|
7
|
+
setup do
|
8
|
+
@qcont = WebComicWithSearchable.create :name => "Questionable Content", :author => "Jeph Jaques"
|
9
|
+
@jhony = WebComicWithSearchable.create :name => "Johnny Wander", :author => "Ananth & Yuko"
|
10
|
+
@ddeeg = WebComicWithSearchable.create :name => "Dominic Deegan", :author => "Mookie"
|
11
|
+
@penny = WebComicWithSearchable.create :name => "Penny Arcade", :author => "Tycho & Gabe"
|
12
|
+
end
|
13
|
+
|
14
|
+
teardown do
|
15
|
+
WebComicWithSearchable.delete_all
|
16
|
+
end
|
17
|
+
|
18
|
+
should "search across all columns" do
|
19
|
+
assert_equal [@penny], WebComicWithSearchable.advanced_search("Penny")
|
20
|
+
assert_equal [@ddeeg], WebComicWithSearchable.advanced_search("Dominic")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "with one column as parameter" do
|
25
|
+
setup do
|
26
|
+
@qcont = WebComicWithSearchableName.create :name => "Questionable Content", :author => "Jeph Jaques"
|
27
|
+
@jhony = WebComicWithSearchableName.create :name => "Johnny Wander", :author => "Ananth & Yuko"
|
28
|
+
@ddeeg = WebComicWithSearchableName.create :name => "Dominic Deegan", :author => "Mookie"
|
29
|
+
@penny = WebComicWithSearchableName.create :name => "Penny Arcade", :author => "Tycho & Gabe"
|
30
|
+
end
|
31
|
+
|
32
|
+
teardown do
|
33
|
+
WebComicWithSearchableName.delete_all
|
34
|
+
end
|
35
|
+
|
36
|
+
should "only search across the given column" do
|
37
|
+
assert_equal [@penny], WebComicWithSearchableName.advanced_search("Penny")
|
38
|
+
assert_empty WebComicWithSearchableName.advanced_search("Tycho")
|
39
|
+
end
|
40
|
+
|
41
|
+
["hello \\", "tebow!" , "food &"].each do |search_term|
|
42
|
+
should "be fine with searching for crazy character #{search_term} with plain search" do
|
43
|
+
# Uses plainto_tsquery
|
44
|
+
assert_equal [], WebComicWithSearchableName.basic_search(search_term)
|
45
|
+
end
|
46
|
+
|
47
|
+
should "be not fine with searching for crazy character #{search_term} with advanced search" do
|
48
|
+
# Uses to_tsquery
|
49
|
+
assert_raise(ActiveRecord::StatementInvalid) do
|
50
|
+
WebComicWithSearchableName.advanced_search(search_term).all
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
should "fuzzy search stuff" do
|
56
|
+
assert_equal [@qcont], WebComicWithSearchableName.fuzzy_search('Questio')
|
57
|
+
end
|
58
|
+
|
59
|
+
should "define :searchable_columns as private" do
|
60
|
+
assert_raise(NoMethodError) { WebComicWithSearchableName.searchable_columns }
|
61
|
+
begin
|
62
|
+
WebComicWithSearchableName.searchable_columns
|
63
|
+
rescue NoMethodError => error
|
64
|
+
assert_match error.message, /private method/
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
should "define #indexable_columns which returns a write-proof Enumerable" do
|
69
|
+
assert_equal(Enumerator, WebComicWithSearchableName.indexable_columns.class)
|
70
|
+
assert_raise(NoMethodError) { WebComicWithSearchableName.indexable_columns[0] = 'foo' }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "with two columns as parameters" do
|
75
|
+
setup do
|
76
|
+
@qcont = WebComicWithSearchableNameAndAuthor.create :name => "Questionable Content", :author => "Jeph Jaques"
|
77
|
+
@jhony = WebComicWithSearchableNameAndAuthor.create :name => "Johnny Wander", :author => "Ananth & Yuko"
|
78
|
+
@ddeeg = WebComicWithSearchableNameAndAuthor.create :name => "Dominic Deegan", :author => "Mookie"
|
79
|
+
@penny = WebComicWithSearchableNameAndAuthor.create :name => "Penny Arcade", :author => "Tycho & Gabe"
|
80
|
+
end
|
81
|
+
|
82
|
+
teardown do
|
83
|
+
WebComicWithSearchableNameAndAuthor.delete_all
|
84
|
+
end
|
85
|
+
|
86
|
+
should "only search across the given column" do
|
87
|
+
assert_equal [@penny], WebComicWithSearchableNameAndAuthor.advanced_search("Penny")
|
88
|
+
assert_equal [@penny], WebComicWithSearchableNameAndAuthor.advanced_search("Tycho")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,216 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
class TextacularTest < Test::Unit::TestCase
|
5
|
+
context "after extending ActiveRecord::Base" do
|
6
|
+
should "not break #respond_to?" do
|
7
|
+
assert_nothing_raised do
|
8
|
+
ARStandIn.respond_to? :abstract_class?
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
should "not break #respond_to? for table-less classes" do
|
13
|
+
assert !NotThere.table_exists?
|
14
|
+
assert_nothing_raised do
|
15
|
+
NotThere.respond_to? :system
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
should "not break #method_missing" do
|
20
|
+
assert_raise(NoMethodError) { ARStandIn.random }
|
21
|
+
begin
|
22
|
+
ARStandIn.random
|
23
|
+
rescue NoMethodError => error
|
24
|
+
assert_match error.message, /undefined method `random'/
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
should "not break #method_missing for table-less classes" do
|
29
|
+
assert !NotThere.table_exists?
|
30
|
+
assert_raise(NoMethodError) { NotThere.random }
|
31
|
+
begin
|
32
|
+
NotThere.random
|
33
|
+
rescue NoMethodError => error
|
34
|
+
assert_match error.message, /undefined method `random'/
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when finding models based on searching a related model" do
|
39
|
+
setup do
|
40
|
+
@qc = TextacularWebComic.create :name => "Questionable Content", :author => "Jeph Jaques"
|
41
|
+
@jw = TextacularWebComic.create :name => "Johnny Wander", :author => "Ananth & Yuko"
|
42
|
+
@pa = TextacularWebComic.create :name => "Penny Arcade", :author => "Tycho & Gabe"
|
43
|
+
|
44
|
+
@gabe = @pa.characters.create :name => 'Gabe', :description => 'the simple one'
|
45
|
+
@tycho = @pa.characters.create :name => 'Tycho', :description => 'the wordy one'
|
46
|
+
@div = @pa.characters.create :name => 'Div', :description => 'a crude divx player with anger management issues'
|
47
|
+
|
48
|
+
@martin = @qc.characters.create :name => 'Martin', :description => 'the insecure protagonist'
|
49
|
+
@faye = @qc.characters.create :name => 'Faye', :description => 'a sarcastic barrista with anger management issues'
|
50
|
+
@pintsize = @qc.characters.create :name => 'Pintsize', :description => 'a crude AnthroPC'
|
51
|
+
|
52
|
+
@ananth = @jw.characters.create :name => 'Ananth', :description => 'Stubble! What is under that hat?!?'
|
53
|
+
@yuko = @jw.characters.create :name => 'Yuko', :description => 'So... small. Carl Sagan haircut.'
|
54
|
+
@john = @jw.characters.create :name => 'John', :description => 'Tall. Anger issues?'
|
55
|
+
@cricket = @jw.characters.create :name => 'Cricket', :description => 'Chirrup!'
|
56
|
+
end
|
57
|
+
|
58
|
+
teardown do
|
59
|
+
TextacularWebComic.delete_all
|
60
|
+
Character.delete_all
|
61
|
+
end
|
62
|
+
|
63
|
+
should "look in the related model with nested searching syntax" do
|
64
|
+
assert_equal [@jw], TextacularWebComic.joins(:characters).advanced_search(:characters => {:description => 'tall'})
|
65
|
+
assert_equal [@pa, @jw, @qc].sort, TextacularWebComic.joins(:characters).advanced_search(:characters => {:description => 'anger'}).sort
|
66
|
+
assert_equal [@pa, @qc].sort, TextacularWebComic.joins(:characters).advanced_search(:characters => {:description => 'crude'}).sort
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "after extending an ActiveRecord::Base subclass" do
|
72
|
+
setup do
|
73
|
+
@zelda = GameExtendedWithTextacular.create :system => "NES", :title => "Legend of Zelda", :description => "A Link to the Past."
|
74
|
+
@mario = GameExtendedWithTextacular.create :system => "NES", :title => "Super Mario Bros.", :description => "The original platformer."
|
75
|
+
@sonic = GameExtendedWithTextacular.create :system => "Genesis", :title => "Sonic the Hedgehog", :description => "Spiky."
|
76
|
+
@dkong = GameExtendedWithTextacular.create :system => "SNES", :title => "Diddy's Kong Quest", :description => "Donkey Kong Country 2"
|
77
|
+
@megam = GameExtendedWithTextacular.create :system => nil, :title => "Mega Man", :description => "Beware Dr. Brain"
|
78
|
+
@sfnes = GameExtendedWithTextacular.create :system => "SNES", :title => "Street Fighter 2", :description => "Yoga Flame!"
|
79
|
+
@sfgen = GameExtendedWithTextacular.create :system => "Genesis", :title => "Street Fighter 2", :description => "Yoga Flame!"
|
80
|
+
@takun = GameExtendedWithTextacular.create :system => "Saturn", :title => "Magical Tarurūto-kun", :description => "カッコイイ!"
|
81
|
+
end
|
82
|
+
|
83
|
+
teardown do
|
84
|
+
GameExtendedWithTextacular.delete_all
|
85
|
+
end
|
86
|
+
|
87
|
+
should "not break respond_to? when connection is unavailable" do
|
88
|
+
GameFailExtendedWithTextacular.establish_connection({:adapter => :postgresql, :database =>'unavailable', :username=>'bad', :pool=>5, :timeout=>5000}) rescue nil
|
89
|
+
|
90
|
+
assert_nothing_raised do
|
91
|
+
GameFailExtendedWithTextacular.respond_to?(:advanced_search)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
should "define a #search method" do
|
96
|
+
assert GameExtendedWithTextacular.respond_to?(:search)
|
97
|
+
end
|
98
|
+
|
99
|
+
context "when searching with a String argument" do
|
100
|
+
should "search across all :string columns if no indexes have been specified" do
|
101
|
+
assert_equal [@mario], GameExtendedWithTextacular.advanced_search("Mario")
|
102
|
+
assert_equal Set.new([@mario, @zelda]), GameExtendedWithTextacular.advanced_search("NES").to_set
|
103
|
+
end
|
104
|
+
|
105
|
+
should "work if the query contains an apostrophe" do
|
106
|
+
assert_equal [@dkong], GameExtendedWithTextacular.advanced_search("Diddy's")
|
107
|
+
end
|
108
|
+
|
109
|
+
should "work if the query contains whitespace" do
|
110
|
+
assert_equal [@megam], GameExtendedWithTextacular.advanced_search("Mega Man")
|
111
|
+
end
|
112
|
+
|
113
|
+
should "work if the query contains an accent" do
|
114
|
+
assert_equal [@takun], GameExtendedWithTextacular.advanced_search("Tarurūto-kun")
|
115
|
+
end
|
116
|
+
|
117
|
+
should "search across records with NULL values" do
|
118
|
+
assert_equal [@megam], GameExtendedWithTextacular.advanced_search("Mega")
|
119
|
+
end
|
120
|
+
|
121
|
+
should "scope consecutively" do
|
122
|
+
assert_equal [@sfgen], GameExtendedWithTextacular.advanced_search("Genesis").advanced_search("Street Fighter")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "when searching with a Hash argument" do
|
127
|
+
should "search across the given columns" do
|
128
|
+
assert_empty GameExtendedWithTextacular.advanced_search(:title => "NES")
|
129
|
+
assert_empty GameExtendedWithTextacular.advanced_search(:system => "Mario")
|
130
|
+
assert_empty GameExtendedWithTextacular.advanced_search(:system => "NES", :title => "Sonic")
|
131
|
+
|
132
|
+
assert_equal [@mario], GameExtendedWithTextacular.advanced_search(:title => "Mario")
|
133
|
+
|
134
|
+
assert_equal 2, GameExtendedWithTextacular.advanced_search(:system => "NES").count
|
135
|
+
|
136
|
+
assert_equal [@zelda], GameExtendedWithTextacular.advanced_search(:system => "NES", :title => "Zelda")
|
137
|
+
assert_equal [@megam], GameExtendedWithTextacular.advanced_search(:title => "Mega")
|
138
|
+
end
|
139
|
+
|
140
|
+
should "scope consecutively" do
|
141
|
+
assert_equal [@sfgen], GameExtendedWithTextacular.advanced_search(:system => "Genesis").advanced_search(:title => "Street Fighter")
|
142
|
+
end
|
143
|
+
|
144
|
+
should "cast non-:string columns as text" do
|
145
|
+
assert_equal [@mario], GameExtendedWithTextacular.advanced_search(:id => @mario.id)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "when using dynamic search methods" do
|
150
|
+
should "generate methods for each :string column" do
|
151
|
+
assert_equal [@mario], GameExtendedWithTextacular.advanced_search_by_title("Mario")
|
152
|
+
assert_equal [@takun], GameExtendedWithTextacular.advanced_search_by_system("Saturn")
|
153
|
+
end
|
154
|
+
|
155
|
+
should "generate methods for each :text column" do
|
156
|
+
assert_equal [@mario], GameExtendedWithTextacular.advanced_search_by_description("platform")
|
157
|
+
end
|
158
|
+
|
159
|
+
should "generate methods for any combination of :string and :text columns" do
|
160
|
+
assert_equal [@mario], GameExtendedWithTextacular.advanced_search_by_title_and_system("Mario", "NES")
|
161
|
+
assert_equal [@sonic], GameExtendedWithTextacular.advanced_search_by_system_and_title("Genesis", "Sonic")
|
162
|
+
assert_equal [@mario], GameExtendedWithTextacular.advanced_search_by_title_and_title("Mario", "Mario")
|
163
|
+
assert_equal [@megam], GameExtendedWithTextacular.advanced_search_by_title_and_description("Man", "Brain")
|
164
|
+
end
|
165
|
+
|
166
|
+
should "generate methods for inclusive searches" do
|
167
|
+
assert_equal Set.new([@megam, @takun]), GameExtendedWithTextacular.advanced_search_by_system_or_title("Saturn", "Mega Man").to_set
|
168
|
+
end
|
169
|
+
|
170
|
+
should "scope consecutively" do
|
171
|
+
assert_equal [@sfgen], GameExtendedWithTextacular.advanced_search_by_system("Genesis").advanced_search_by_title("Street Fighter")
|
172
|
+
end
|
173
|
+
|
174
|
+
should "generate methods for non-:string columns" do
|
175
|
+
assert_equal [@mario], GameExtendedWithTextacular.advanced_search_by_id(@mario.id)
|
176
|
+
end
|
177
|
+
|
178
|
+
should "work with #respond_to?" do
|
179
|
+
assert GameExtendedWithTextacular.respond_to?(:advanced_search_by_system)
|
180
|
+
assert GameExtendedWithTextacular.respond_to?(:advanced_search_by_title)
|
181
|
+
assert GameExtendedWithTextacular.respond_to?(:advanced_search_by_system_and_title)
|
182
|
+
assert GameExtendedWithTextacular.respond_to?(:advanced_search_by_system_or_title)
|
183
|
+
assert GameExtendedWithTextacular.respond_to?(:advanced_search_by_title_and_title_and_title)
|
184
|
+
assert GameExtendedWithTextacular.respond_to?(:advanced_search_by_id)
|
185
|
+
|
186
|
+
assert !GameExtendedWithTextacular.respond_to?(:advanced_search_by_title_and_title_or_title)
|
187
|
+
end
|
188
|
+
|
189
|
+
should "allow for 2 arguments to #respond_to?" do
|
190
|
+
assert GameExtendedWithTextacular.respond_to?(:normalize, true)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context "when searching after selecting columns to return" do
|
195
|
+
should "not fetch extra columns" do
|
196
|
+
assert_raise(ActiveModel::MissingAttributeError) do
|
197
|
+
GameExtendedWithTextacular.select(:title).advanced_search("Mario").first.system
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context "when setting a custom search language" do
|
203
|
+
setup do
|
204
|
+
GameExtendedWithTextacularAndCustomLanguage.create :system => "PS3", :title => "Harry Potter & the Deathly Hallows"
|
205
|
+
end
|
206
|
+
|
207
|
+
teardown do
|
208
|
+
GameExtendedWithTextacularAndCustomLanguage.delete_all
|
209
|
+
end
|
210
|
+
|
211
|
+
should "still find results" do
|
212
|
+
assert_not_empty GameExtendedWithTextacularAndCustomLanguage.advanced_search_by_title("harry")
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
metadata
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: textacular
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 3.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ben Hamill
|
9
|
+
- ecin
|
10
|
+
- Aaron Patterson
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2013-02-27 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: pg
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.11.0
|
24
|
+
type: :development
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
none: false
|
28
|
+
requirements:
|
29
|
+
- - ~>
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: 0.11.0
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: shoulda
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ~>
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 2.11.3
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 2.11.3
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rake
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 0.9.0
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ~>
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 0.9.0
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: pry
|
66
|
+
requirement: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
type: :development
|
73
|
+
prerelease: false
|
74
|
+
version_requirements: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ! '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: pry-doc
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: activerecord
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.0'
|
104
|
+
- - <
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '4.1'
|
107
|
+
type: :runtime
|
108
|
+
prerelease: false
|
109
|
+
version_requirements: !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ! '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '3.0'
|
115
|
+
- - <
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '4.1'
|
118
|
+
description: ! "Textacular exposes full text search capabilities from PostgreSQL,
|
119
|
+
extending\n ActiveRecord with scopes making search easy and fun!"
|
120
|
+
email:
|
121
|
+
- git-commits@benhamill.com
|
122
|
+
- ecin@copypastel.com
|
123
|
+
executables: []
|
124
|
+
extensions: []
|
125
|
+
extra_rdoc_files: []
|
126
|
+
files:
|
127
|
+
- CHANGELOG.md
|
128
|
+
- Gemfile
|
129
|
+
- README.md
|
130
|
+
- Rakefile
|
131
|
+
- lib/textacular.rb
|
132
|
+
- lib/textacular/full_text_indexer.rb
|
133
|
+
- lib/textacular/postgres_module_installer.rb
|
134
|
+
- lib/textacular/rails.rb
|
135
|
+
- lib/textacular/searchable.rb
|
136
|
+
- lib/textacular/tasks.rb
|
137
|
+
- lib/textacular/version.rb
|
138
|
+
- spec/config.yml.example
|
139
|
+
- spec/fixtures/character.rb
|
140
|
+
- spec/fixtures/game.rb
|
141
|
+
- spec/fixtures/webcomic.rb
|
142
|
+
- spec/spec_helper.rb
|
143
|
+
- spec/textacular/searchable_spec.rb
|
144
|
+
- spec/textacular_spec.rb
|
145
|
+
homepage: http://textacular.github.com/textacular
|
146
|
+
licenses:
|
147
|
+
- MIT
|
148
|
+
post_install_message:
|
149
|
+
rdoc_options: []
|
150
|
+
require_paths:
|
151
|
+
- lib
|
152
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
159
|
+
none: false
|
160
|
+
requirements:
|
161
|
+
- - ! '>='
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '0'
|
164
|
+
requirements: []
|
165
|
+
rubyforge_project:
|
166
|
+
rubygems_version: 1.8.23
|
167
|
+
signing_key:
|
168
|
+
specification_version: 3
|
169
|
+
summary: Textacular exposes full text search capabilities from PostgreSQL
|
170
|
+
test_files:
|
171
|
+
- spec/config.yml.example
|
172
|
+
- spec/fixtures/character.rb
|
173
|
+
- spec/fixtures/game.rb
|
174
|
+
- spec/fixtures/webcomic.rb
|
175
|
+
- spec/spec_helper.rb
|
176
|
+
- spec/textacular/searchable_spec.rb
|
177
|
+
- spec/textacular_spec.rb
|
178
|
+
has_rdoc:
|