pose 0.0.2

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/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2011 Kevin Goslar
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,91 @@
1
+ # Pose
2
+
3
+ Pose ("Polymorphic Search") allows fulltext search for ActiveRecord objects.
4
+
5
+ * Searches over several ActiveRecord classes at once.
6
+ * The searchable fulltext content per document can be freely customized.
7
+ * Uses the Rails database, no sparate search engines are necessary.
8
+ * The algorithm is designed to work with any data store that allows for range queries: SQL and NoSQL.
9
+ * The search runs very fast, doing simple queries over fully indexed columns.
10
+ * The search index provides data for autocomplete search fields.
11
+
12
+
13
+ # Installation
14
+
15
+ 1. Add the gem to your Gemfile.
16
+
17
+ gem 'pose'
18
+
19
+ 2. Update your gem bundle.
20
+
21
+ $ bundle install
22
+
23
+ 3. Create the database tables for pose.
24
+
25
+ $ rails generate pose
26
+ $ rake db:migrate
27
+
28
+ Pose creates two tables in your database:
29
+
30
+ * _pose_words_: index of all the words that occur in the searchable content.
31
+ * _pose_assignments_: lists which word occurs in which document.
32
+
33
+
34
+ # Make your ActiveRecord models searchable.
35
+
36
+ class MyClass < ActiveRecord::Base
37
+
38
+ # This line tells Pose that your class should be searchable.
39
+ # Once Pose knows that, it will update the search index every time an instance is saved or deleted.
40
+ #
41
+ # The given block must return the searchble content as a string.
42
+ # Note that you can return whatever content you want here,
43
+ # not only data from this object but also data from related objects, class names, etc.
44
+ posify do
45
+
46
+ # Only active instances should show up in search results.
47
+ return unless status == :active
48
+
49
+ # Return the fulltext content.
50
+ [ self.foo,
51
+ self.parent.bar,
52
+ self.children.map &:name ].join ' '
53
+ end
54
+ end
55
+
56
+
57
+ # Maintain the search index.
58
+
59
+ The search index is automatically updated when Objects are saved or deleted.
60
+ To add existing records in the database without having to save them again,
61
+ or recreate the search index, please run
62
+
63
+ rake pose:reindex_all[MyClass]
64
+
65
+
66
+ # Perform a search
67
+
68
+ result = Pose.search 'foo', [MyClass, MyOtherClass]
69
+
70
+ This searches for all instances of MyClass and MyOtherClass that contain the word 'foo'.
71
+ The method returns a hash that looks like this:
72
+
73
+ {
74
+ MyClass => [ <myclass instance 1>, <myclass instance 2> ],
75
+ MyOtherClass => [ ],
76
+ }
77
+
78
+ In this example, it found two results of type _MyClass_ and no results of type _MyOtherClass_.
79
+
80
+ Happy searching! :)
81
+
82
+
83
+ # Development
84
+
85
+ If you find a bug, have a question, or a better idea, please open an issue on the
86
+ <a href="https://github.com/kevgo/pose/issues">Pose issue tracker</a>.
87
+ Or, clone the repository, make your changes, and submit a pull request.
88
+
89
+ ## Unit Tests
90
+
91
+ rake spec
data/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ require 'rspec/core/rake_task'
8
+
9
+ Bundler::GemHelper.install_tasks
10
+
11
+ desc 'Default: run the specs and features.'
12
+ task :default => 'spec:unit' do
13
+ system("bundle exec rake spec")
14
+ end
15
+
16
+ namespace :spec do
17
+
18
+ desc "Run unit specs"
19
+ RSpec::Core::RakeTask.new('unit') do |t|
20
+ t.pattern = 'spec/{*_spec.rb}'
21
+ end
22
+ end
23
+
24
+ desc "Run the unit tests"
25
+ task :spec => ['spec:unit']
26
+
@@ -0,0 +1,341 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
+ <title>
7
+ Module: Pose::InstanceMethods
8
+
9
+ &mdash; Documentation by YARD 0.7.3
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="../css/style.css" type="text/css" media="screen" charset="utf-8" />
14
+
15
+ <link rel="stylesheet" href="../css/common.css" type="text/css" media="screen" charset="utf-8" />
16
+
17
+ <script type="text/javascript" charset="utf-8">
18
+ relpath = '..';
19
+ if (relpath != '') relpath += '/';
20
+ </script>
21
+
22
+ <script type="text/javascript" charset="utf-8" src="../js/jquery.js"></script>
23
+
24
+ <script type="text/javascript" charset="utf-8" src="../js/app.js"></script>
25
+
26
+
27
+ </head>
28
+ <body>
29
+ <script type="text/javascript" charset="utf-8">
30
+ if (window.top.frames.main) document.body.className = 'frames';
31
+ </script>
32
+
33
+ <div id="header">
34
+ <div id="menu">
35
+
36
+ <a href="../_index.html">Index (I)</a> &raquo;
37
+ <span class='title'><span class='object_link'><a href="../Pose.html" title="Pose (module)">Pose</a></span></span>
38
+ &raquo;
39
+ <span class="title">InstanceMethods</span>
40
+
41
+
42
+ <div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
43
+ </div>
44
+
45
+ <div id="search">
46
+
47
+ <a id="class_list_link" href="#">Class List</a>
48
+
49
+ <a id="method_list_link" href="#">Method List</a>
50
+
51
+ <a id="file_list_link" href="#">File List</a>
52
+
53
+ </div>
54
+ <div class="clear"></div>
55
+ </div>
56
+
57
+ <iframe id="search_frame"></iframe>
58
+
59
+ <div id="content"><h1>Module: Pose::InstanceMethods
60
+
61
+
62
+
63
+ </h1>
64
+
65
+ <dl class="box">
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+
74
+ <dt class="r1 last">Defined in:</dt>
75
+ <dd class="r1 last">lib/pose.rb</dd>
76
+
77
+ </dl>
78
+ <div class="clear"></div>
79
+
80
+
81
+
82
+
83
+
84
+
85
+
86
+ <h2>
87
+ Instance Method Summary
88
+ <small>(<a href="#" class="summary_toggle">collapse</a>)</small>
89
+ </h2>
90
+
91
+ <ul class="summary">
92
+
93
+ <li class="public ">
94
+ <span class="summary_signature">
95
+
96
+ <a href="#delete_pose_index-instance_method" title="#delete_pose_index (instance method)">- (Object) <strong>delete_pose_index</strong> </a>
97
+
98
+
99
+
100
+ </span>
101
+
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+ <span class="summary_desc"><div class='inline'>Removes this objects from the search index.</div></span>
110
+
111
+ </li>
112
+
113
+
114
+ <li class="public ">
115
+ <span class="summary_signature">
116
+
117
+ <a href="#update_pose_index-instance_method" title="#update_pose_index (instance method)">- (Object) <strong>update_pose_index</strong> </a>
118
+
119
+
120
+
121
+ </span>
122
+
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+ <span class="summary_desc"><div class='inline'>Updates the associated words for this object in the database.</div></span>
131
+
132
+ </li>
133
+
134
+
135
+ <li class="public ">
136
+ <span class="summary_signature">
137
+
138
+ <a href="#update_pose_words-instance_method" title="#update_pose_words (instance method)">- (Object) <strong>update_pose_words</strong> </a>
139
+
140
+
141
+
142
+ </span>
143
+
144
+
145
+
146
+
147
+
148
+
149
+
150
+
151
+ <span class="summary_desc"><div class='inline'>Helper method.</div></span>
152
+
153
+ </li>
154
+
155
+
156
+ </ul>
157
+
158
+
159
+
160
+
161
+ <div id="instance_method_details" class="method_details_list">
162
+ <h2>Instance Method Details</h2>
163
+
164
+
165
+ <div class="method_details first">
166
+ <p class="signature first" id="delete_pose_index-instance_method">
167
+
168
+ - (<tt>Object</tt>) <strong>delete_pose_index</strong>
169
+
170
+
171
+
172
+ </p><div class="docstring">
173
+ <div class="discussion">
174
+ Removes this objects from the search index.
175
+
176
+ </div>
177
+ </div>
178
+ <div class="tags">
179
+
180
+
181
+ </div><table class="source_code">
182
+ <tr>
183
+ <td>
184
+ <pre class="lines">
185
+
186
+
187
+ 29
188
+ 30
189
+ 31
190
+ 32</pre>
191
+ </td>
192
+ <td>
193
+ <pre class="code"><span class="info file"># File 'lib/pose.rb', line 29</span>
194
+
195
+ <span class='def def kw'>def</span> <span class='delete_pose_index identifier id'>delete_pose_index</span>
196
+ <span class='return return kw'>return</span> <span class='if if_mod kw'>if</span> <span class='Rails constant id'>Rails</span><span class='dot token'>.</span><span class='env identifier id'>env</span> <span class='eq op'>==</span> <span class='string val'>'test'</span> <span class='and and kw'>and</span> <span class='notop op'>!</span><span class='CONFIGURATION constant id'>CONFIGURATION</span><span class='lbrack token'>[</span><span class='symbol val'>:search_in_tests</span><span class='rbrack token'>]</span>
197
+ <span class='self self kw'>self</span><span class='dot token'>.</span><span class='words identifier id'>words</span><span class='dot token'>.</span><span class='clear identifier id'>clear</span>
198
+ <span class='end end kw'>end</span>
199
+ </pre>
200
+ </td>
201
+ </tr>
202
+ </table>
203
+ </div>
204
+
205
+ <div class="method_details ">
206
+ <p class="signature " id="update_pose_index-instance_method">
207
+
208
+ - (<tt>Object</tt>) <strong>update_pose_index</strong>
209
+
210
+
211
+
212
+ </p><div class="docstring">
213
+ <div class="discussion">
214
+ Updates the associated words for this object in the database.
215
+
216
+ </div>
217
+ </div>
218
+ <div class="tags">
219
+
220
+
221
+ </div><table class="source_code">
222
+ <tr>
223
+ <td>
224
+ <pre class="lines">
225
+
226
+
227
+ 20
228
+ 21
229
+ 22
230
+ 23
231
+ 24
232
+ 25
233
+ 26</pre>
234
+ </td>
235
+ <td>
236
+ <pre class="code"><span class="info file"># File 'lib/pose.rb', line 20</span>
237
+
238
+ <span class='def def kw'>def</span> <span class='update_pose_index identifier id'>update_pose_index</span>
239
+
240
+ <span class='comment val'># Don't do this in tests.</span>
241
+ <span class='return return kw'>return</span> <span class='if if_mod kw'>if</span> <span class='Rails constant id'>Rails</span><span class='dot token'>.</span><span class='env identifier id'>env</span> <span class='eq op'>==</span> <span class='string val'>'test'</span> <span class='and and kw'>and</span> <span class='notop op'>!</span><span class='CONFIGURATION constant id'>CONFIGURATION</span><span class='lbrack token'>[</span><span class='symbol val'>:search_in_tests</span><span class='rbrack token'>]</span>
242
+
243
+ <span class='update_pose_words identifier id'>update_pose_words</span>
244
+ <span class='end end kw'>end</span>
245
+ </pre>
246
+ </td>
247
+ </tr>
248
+ </table>
249
+ </div>
250
+
251
+ <div class="method_details ">
252
+ <p class="signature " id="update_pose_words-instance_method">
253
+
254
+ - (<tt>Object</tt>) <strong>update_pose_words</strong>
255
+
256
+
257
+
258
+ </p><div class="docstring">
259
+ <div class="discussion">
260
+ Helper method.
261
+ Updates the search words with the text returned by search_strings.
262
+
263
+ </div>
264
+ </div>
265
+ <div class="tags">
266
+
267
+
268
+ </div><table class="source_code">
269
+ <tr>
270
+ <td>
271
+ <pre class="lines">
272
+
273
+
274
+ 36
275
+ 37
276
+ 38
277
+ 39
278
+ 40
279
+ 41
280
+ 42
281
+ 43
282
+ 44
283
+ 45
284
+ 46
285
+ 47
286
+ 48
287
+ 49
288
+ 50
289
+ 51
290
+ 52
291
+ 53
292
+ 54
293
+ 55
294
+ 56
295
+ 57
296
+ 58</pre>
297
+ </td>
298
+ <td>
299
+ <pre class="code"><span class="info file"># File 'lib/pose.rb', line 36</span>
300
+
301
+ <span class='def def kw'>def</span> <span class='update_pose_words identifier id'>update_pose_words</span>
302
+
303
+ <span class='comment val'># Step 1: get an array of all words for the current object.</span>
304
+ <span class='new_words identifier id'>new_words</span> <span class='assign token'>=</span> <span class='lbrack token'>[</span><span class='rbrack token'>]</span>
305
+ <span class='search_strings identifier id'>search_strings</span> <span class='assign token'>=</span> <span class='self self kw'>self</span><span class='dot token'>.</span><span class='pose_content identifier id'>pose_content</span>
306
+ <span class='search_strings identifier id'>search_strings</span><span class='dot token'>.</span><span class='flatten identifier id'>flatten</span><span class='dot token'>.</span><span class='each identifier id'>each</span> <span class='do do kw'>do</span> <span class='bitor op'>|</span><span class='text identifier id'>text</span><span class='bitor op'>|</span>
307
+ <span class='next next kw'>next</span> <span class='unless unless_mod kw'>unless</span> <span class='text identifier id'>text</span>
308
+ <span class='text identifier id'>text</span><span class='dot token'>.</span><span class='to_s identifier id'>to_s</span><span class='dot token'>.</span><span class='split identifier id'>split</span><span class='lparen token'>(</span><span class='string val'>' '</span><span class='rparen token'>)</span><span class='dot token'>.</span><span class='each identifier id'>each</span> <span class='do do kw'>do</span> <span class='bitor op'>|</span><span class='word identifier id'>word</span><span class='bitor op'>|</span>
309
+ <span class='new_words identifier id'>new_words</span><span class='dot token'>.</span><span class='concat identifier id'>concat</span> <span class='Pose constant id'>Pose</span><span class='dot token'>.</span><span class='root_word identifier id'>root_word</span><span class='lparen token'>(</span><span class='word identifier id'>word</span><span class='rparen token'>)</span>
310
+ <span class='end end kw'>end</span>
311
+ <span class='end end kw'>end</span>
312
+ <span class='new_words identifier id'>new_words</span><span class='dot token'>.</span><span class='uniq! fid id'>uniq!</span>
313
+
314
+ <span class='comment val'># Step 2: Add new words to the search index.</span>
315
+ <span class='Pose constant id'>Pose</span><span class='dot token'>.</span><span class='get_words_to_add identifier id'>get_words_to_add</span><span class='lparen token'>(</span><span class='self self kw'>self</span><span class='dot token'>.</span><span class='pose_words identifier id'>pose_words</span><span class='comma token'>,</span> <span class='new_words identifier id'>new_words</span><span class='rparen token'>)</span><span class='dot token'>.</span><span class='each identifier id'>each</span> <span class='do do kw'>do</span> <span class='bitor op'>|</span><span class='word_to_add identifier id'>word_to_add</span><span class='bitor op'>|</span>
316
+ <span class='self self kw'>self</span><span class='dot token'>.</span><span class='pose_words identifier id'>pose_words</span> <span class='lshft op'>&lt;&lt;</span> <span class='PoseWord constant id'>PoseWord</span><span class='dot token'>.</span><span class='find_or_create_by_text identifier id'>find_or_create_by_text</span><span class='lparen token'>(</span><span class='word_to_add identifier id'>word_to_add</span><span class='rparen token'>)</span>
317
+ <span class='end end kw'>end</span>
318
+
319
+ <span class='comment val'># Step 3: Remove now obsolete words from search index.</span>
320
+ <span class='Pose constant id'>Pose</span><span class='dot token'>.</span><span class='get_words_to_remove identifier id'>get_words_to_remove</span><span class='lparen token'>(</span><span class='self self kw'>self</span><span class='dot token'>.</span><span class='pose_words identifier id'>pose_words</span><span class='comma token'>,</span> <span class='new_words identifier id'>new_words</span><span class='rparen token'>)</span><span class='dot token'>.</span><span class='each identifier id'>each</span> <span class='do do kw'>do</span> <span class='bitor op'>|</span><span class='word_to_remove identifier id'>word_to_remove</span><span class='bitor op'>|</span>
321
+ <span class='self self kw'>self</span><span class='dot token'>.</span><span class='pose_words identifier id'>pose_words</span><span class='dot token'>.</span><span class='delete identifier id'>delete</span> <span class='word_to_remove identifier id'>word_to_remove</span>
322
+ <span class='end end kw'>end</span>
323
+ <span class='end end kw'>end</span>
324
+ </pre>
325
+ </td>
326
+ </tr>
327
+ </table>
328
+ </div>
329
+
330
+ </div>
331
+
332
+ </div>
333
+
334
+ <div id="footer">
335
+ Generated on Wed Nov 16 11:48:27 2011 by
336
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
337
+ 0.7.3 (ruby-1.8.7).
338
+ </div>
339
+
340
+ </body>
341
+ </html>