haystack 1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7b8c30f7e33f14b1f9245cb2b812d6848f81ff5d
4
+ data.tar.gz: 4d0fa6b2dcefcd43fb665ad401db66d4b84850cc
5
+ SHA512:
6
+ metadata.gz: ab078d95aadcf856ef640641e0a84261d3067105e31c2ebb4b3df0b2794f229a23fcf45848621271c321291c88ab55fce7dfe2e4b03ad6c33e0435e24e7d0b74
7
+ data.tar.gz: ef416f0b4d889f0346159b6d79d6b58a06f32f91b571821da94619f1ff4be94a6e373e5db1fe7b12f085812f66c1622fe2be578dc3e4778a46e6f6970eaabe34
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 YOURNAME
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.md ADDED
@@ -0,0 +1,14 @@
1
+ # Haystack
2
+ **Haystack** is a small searching gem. It was developed based on work for [Cambridge Systematics](http://www.camsys.com) TransAM Asset Management platform. It is designed to be
3
+
4
+ + driven by rails conventions
5
+ + easy to comprehend
6
+ + simple to extend
7
+
8
+ ## Setup
9
+ Haystack has the smarts to search for you, but you'll need to tell it about your domain. For this purposes, Haystack comes with built in generators to create the searchers you need. `rails g searcher User` will create an `app/searchers/` directory (if it's the first time you created a searcher), and place a UserSearcher model in it. It will also create `app/views/searchers/` (again, only if it's the first time) and add two view files (a search form and a results view), but that's all that's needed!
10
+
11
+ ## Usage
12
+ TODO
13
+
14
+ ######This is released using the MIT-LICENSE. Go nuts, everybody.
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Haystack'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module Haystack
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,20 @@
1
+ require_dependency "haystack/application_controller"
2
+
3
+ class Haystack::SearchesController < ApplicationController
4
+ def new
5
+ @data = []
6
+ @searcher = "#{params[:type]}Searcher".constantize.new
7
+ end
8
+
9
+ def create
10
+ @searcher = "#{params[:type]}Searcher".constantize.new
11
+ @data = @searcher.data
12
+
13
+ respond_to do |format|
14
+ format.html { render 'new' }
15
+ format.js { render 'new' }
16
+ format.json { render :json => @data }
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,4 @@
1
+ module Haystack
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Haystack
2
+ module SearchesHelper
3
+ end
4
+ end
@@ -0,0 +1,66 @@
1
+ #
2
+ # Abstract class holding all common search functionality
3
+ #
4
+ module Haystack
5
+ class BaseSearcher
6
+
7
+ #performs ActiveRecord-like mass assignment of attributes
8
+ def initialize(attributes = {})
9
+ mass_assign(attributes)
10
+ end
11
+
12
+ # Caches the rows
13
+ def data
14
+ @data ||= perform_query
15
+ end
16
+
17
+ def to_s
18
+ conditions
19
+ end
20
+
21
+ protected
22
+
23
+ #############################################################################
24
+ # Creation methods
25
+ #############################################################################
26
+
27
+ # requires each attribute in the hash to be names the same as the class property
28
+ def mass_assign(attributes)
29
+ attributes.each do |attribute, value|
30
+ respond_to?("#{attribute}=") && send("#{attribute}=", value)
31
+ end
32
+ end
33
+
34
+ #############################################################################
35
+ # Querying methods
36
+ #############################################################################
37
+ def perform_query
38
+ # Reduce as in map-reduce- ANDs together multiple SQL queries
39
+ # while still lazy-loading them
40
+ condition_part_array.reduce(:merge)
41
+ end
42
+
43
+ # For each param passed from the front-end, fire a "*_conditions" method
44
+ def condition_part_array
45
+ ar_relation_array = []
46
+ self.instance_variables.each do |ivar| # e.g. :@name, :@phone
47
+ new_method_name = "#{ivar.to_s.sub('@','')}_conditions"
48
+ ar_relation_array << self.send(new_method_name)
49
+ end
50
+ ar_relation_array
51
+ end
52
+
53
+ # method_missing will, when passed "_conditions" methods, create an equality-
54
+ # based AR:Relation
55
+ def method_missing(meth, *args, &block)
56
+ # NOTE: We are intentionally setting regex_match_data var here, NOT ==
57
+ if regex_match_data = /(.*?)_conditions/.match(meth) # match returns nil
58
+ hash = {}
59
+ hash[regex_match_data[1]] = self.instance_variable_get(("@"+regex_match_data[1]))
60
+ self.class::BASE.send(:where, hash) # self.class::BASE = BASE for the subclass
61
+ else
62
+ super
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Haystack</title>
5
+ <%= stylesheet_link_tag "haystack/application", media: "all" %>
6
+ <%= javascript_include_tag "haystack/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,161 @@
1
+ # Use this setup block to configure all options available in SimpleForm.
2
+ SimpleForm.setup do |config|
3
+ # Wrappers are used by the form builder to generate a
4
+ # complete input. You can remove any component from the
5
+ # wrapper, change the order or even add your own to the
6
+ # stack. The options given below are used to wrap the
7
+ # whole input.
8
+ config.wrappers :default, class: :input,
9
+ hint_class: :field_with_hint, error_class: :field_with_errors do |b|
10
+ ## Extensions enabled by default
11
+ # Any of these extensions can be disabled for a
12
+ # given input by passing: `f.input EXTENSION_NAME => false`.
13
+ # You can make any of these extensions optional by
14
+ # renaming `b.use` to `b.optional`.
15
+
16
+ # Determines whether to use HTML5 (:email, :url, ...)
17
+ # and required attributes
18
+ b.use :html5
19
+
20
+ # Calculates placeholders automatically from I18n
21
+ # You can also pass a string as f.input placeholder: "Placeholder"
22
+ b.use :placeholder
23
+
24
+ ## Optional extensions
25
+ # They are disabled unless you pass `f.input EXTENSION_NAME => :lookup`
26
+ # to the input. If so, they will retrieve the values from the model
27
+ # if any exists. If you want to enable the lookup for any of those
28
+ # extensions by default, you can change `b.optional` to `b.use`.
29
+
30
+ # Calculates maxlength from length validations for string inputs
31
+ b.optional :maxlength
32
+
33
+ # Calculates pattern from format validations for string inputs
34
+ b.optional :pattern
35
+
36
+ # Calculates min and max from length validations for numeric inputs
37
+ b.optional :min_max
38
+
39
+ # Calculates readonly automatically from readonly attributes
40
+ b.optional :readonly
41
+
42
+ ## Inputs
43
+ b.use :label_input
44
+ b.use :hint, wrap_with: { tag: :span, class: :hint }
45
+ b.use :error, wrap_with: { tag: :span, class: :error }
46
+
47
+ ## full_messages_for
48
+ # If you want to display the full error message for the attribute, you can
49
+ # use the component :full_error, like:
50
+ #
51
+ # b.use :full_error, wrap_with: { tag: :span, class: :error }
52
+ end
53
+
54
+ # The default wrapper to be used by the FormBuilder.
55
+ config.default_wrapper = :default
56
+
57
+ # Define the way to render check boxes / radio buttons with labels.
58
+ # Defaults to :nested for bootstrap config.
59
+ # inline: input + label
60
+ # nested: label > input
61
+ config.boolean_style = :nested
62
+
63
+ # Default class for buttons
64
+ config.button_class = 'btn'
65
+
66
+ # Method used to tidy up errors. Specify any Rails Array method.
67
+ # :first lists the first message for each field.
68
+ # Use :to_sentence to list all errors for each field.
69
+ # config.error_method = :first
70
+
71
+ # Default tag used for error notification helper.
72
+ config.error_notification_tag = :div
73
+
74
+ # CSS class to add for error notification helper.
75
+ config.error_notification_class = 'error_notification'
76
+
77
+ # ID to add for error notification helper.
78
+ # config.error_notification_id = nil
79
+
80
+ # Series of attempts to detect a default label method for collection.
81
+ # config.collection_label_methods = [ :to_label, :name, :title, :to_s ]
82
+
83
+ # Series of attempts to detect a default value method for collection.
84
+ # config.collection_value_methods = [ :id, :to_s ]
85
+
86
+ # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
87
+ # config.collection_wrapper_tag = nil
88
+
89
+ # You can define the class to use on all collection wrappers. Defaulting to none.
90
+ # config.collection_wrapper_class = nil
91
+
92
+ # You can wrap each item in a collection of radio/check boxes with a tag,
93
+ # defaulting to :span. Please note that when using :boolean_style = :nested,
94
+ # SimpleForm will force this option to be a label.
95
+ # config.item_wrapper_tag = :span
96
+
97
+ # You can define a class to use in all item wrappers. Defaulting to none.
98
+ # config.item_wrapper_class = nil
99
+
100
+ # How the label text should be generated altogether with the required text.
101
+ # config.label_text = lambda { |label, required, explicit_label| "#{required} #{label}" }
102
+
103
+ # You can define the class to use on all labels. Default is nil.
104
+ # config.label_class = nil
105
+
106
+ # You can define the class to use on all forms. Default is simple_form.
107
+ # config.form_class = :simple_form
108
+
109
+ # You can define which elements should obtain additional classes
110
+ # config.generate_additional_classes_for = [:wrapper, :label, :input]
111
+
112
+ # Whether attributes are required by default (or not). Default is true.
113
+ # config.required_by_default = true
114
+
115
+ # Tell browsers whether to use the native HTML5 validations (novalidate form option).
116
+ # These validations are enabled in SimpleForm's internal config but disabled by default
117
+ # in this configuration, which is recommended due to some quirks from different browsers.
118
+ # To stop SimpleForm from generating the novalidate option, enabling the HTML5 validations,
119
+ # change this configuration to true.
120
+ config.browser_validations = false
121
+
122
+ # Collection of methods to detect if a file type was given.
123
+ # config.file_methods = [ :mounted_as, :file?, :public_filename ]
124
+
125
+ # Custom mappings for input types. This should be a hash containing a regexp
126
+ # to match as key, and the input type that will be used when the field name
127
+ # matches the regexp as value.
128
+ # config.input_mappings = { /count/ => :integer }
129
+
130
+ # Custom wrappers for input types. This should be a hash containing an input
131
+ # type as key and the wrapper that will be used for all inputs with specified type.
132
+ # config.wrapper_mappings = { string: :prepend }
133
+
134
+ # Default priority for time_zone inputs.
135
+ # config.time_zone_priority = nil
136
+
137
+ # Default priority for country inputs.
138
+ # config.country_priority = nil
139
+
140
+ # When false, do not use translations for labels.
141
+ # config.translate_labels = true
142
+
143
+ # Automatically discover new inputs in Rails' autoload path.
144
+ # config.inputs_discovery = true
145
+
146
+ # Cache SimpleForm inputs discovery
147
+ # config.cache_discovery = !Rails.env.development?
148
+
149
+ # Default class for inputs
150
+ # config.input_class = nil
151
+
152
+ # Define the default class of the input wrapper of the boolean input.
153
+ config.boolean_label_class = 'checkbox'
154
+
155
+ # Defines if the default input wrapper class should be included in radio
156
+ # collection wrappers.
157
+ # config.include_default_input_wrapper_class = true
158
+
159
+ # Defines which i18n scope will be used in Simple Form.
160
+ # config.i18n_scope = 'simple_form'
161
+ end
@@ -0,0 +1,167 @@
1
+ # Use this setup block to configure all options available in SimpleForm.
2
+ SimpleForm.setup do |config|
3
+ config.error_notification_class = 'alert alert-danger'
4
+ config.button_class = 'btn btn-default'
5
+ config.boolean_label_class = nil
6
+
7
+ config.wrappers :vertical_prepend, tag: 'div', class: "form-group", error_class: 'has-error' do |b|
8
+ b.use :html5
9
+ b.use :placeholder
10
+ b.use :label, class: 'control-label'
11
+
12
+ b.wrapper tag: 'div', class: 'input-group' do |input|
13
+ input.use :input, class: 'form-control'
14
+ input.use :hint, wrap_with: { tag: 'span', class: 'help-block' }
15
+ input.use :error, wrap_with: { tag: 'p', class: 'help-inline' }
16
+ end
17
+ end
18
+
19
+ config.wrappers :vertical_append, tag: 'div', class: "form-group", error_class: 'has-error' do |b|
20
+ b.use :html5
21
+ b.use :placeholder
22
+ b.use :label, class: 'control-label'
23
+
24
+ b.wrapper tag: 'div', class: 'input-group' do |input|
25
+ input.use :input, class: 'form-control'
26
+ input.use :hint, wrap_with: { tag: 'span', class: 'help-block' }
27
+ input.use :error, wrap_with: { tag: 'p', class: 'help-inline' }
28
+ end
29
+ end
30
+
31
+ config.wrappers :vertical_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
32
+ b.use :html5
33
+ b.use :placeholder
34
+ b.use :label, class: 'control-label'
35
+
36
+ b.wrapper tag: 'div' do |ba|
37
+ ba.use :input, class: 'form-control'
38
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
39
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
40
+ end
41
+ end
42
+
43
+ config.wrappers :vertical_form_sm, tag: 'div', class: 'form-group-sm', error_class: 'has-error' do |b|
44
+ b.use :html5
45
+ b.use :placeholder
46
+ b.use :label, class: 'control-label'
47
+
48
+ b.wrapper tag: 'div' do |ba|
49
+ ba.use :input, class: 'form-control'
50
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
51
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
52
+ end
53
+ end
54
+
55
+ config.wrappers :vertical_file_input, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
56
+ b.use :html5
57
+ b.use :placeholder
58
+ b.use :label, class: 'control-label'
59
+
60
+ b.wrapper tag: 'div' do |ba|
61
+ ba.use :input
62
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
63
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
64
+ end
65
+ end
66
+
67
+ config.wrappers :vertical_boolean, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
68
+ b.use :html5
69
+ b.use :placeholder
70
+
71
+ b.wrapper tag: 'div', class: 'checkbox' do |ba|
72
+ ba.use :label_input
73
+ end
74
+
75
+ b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
76
+ b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
77
+ end
78
+
79
+ config.wrappers :vertical_radio_and_checkboxes, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
80
+ b.use :html5
81
+ b.use :placeholder
82
+ b.use :label_input
83
+ b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
84
+ b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
85
+ end
86
+
87
+ config.wrappers :horizontal_prepend, tag: 'div', class: "form-group", error_class: 'has-error' do |b|
88
+ b.use :html5
89
+ b.use :placeholder
90
+ b.use :label, class: 'col-sm-3 control-label'
91
+
92
+ b.wrapper tag: 'div', class: 'col-sm-9 input-group' do |input|
93
+ input.use :input, class: 'form-control'
94
+ input.use :hint, wrap_with: { tag: 'span', class: 'help-block' }
95
+ input.use :error, wrap_with: { tag: 'p', class: 'help-inline' }
96
+ end
97
+ end
98
+
99
+ config.wrappers :horizontal_append, tag: 'div', class: "form-group", error_class: 'has-error' do |b|
100
+ b.use :html5
101
+ b.use :placeholder
102
+ b.use :label, class: 'col-sm-3 control-label'
103
+
104
+ b.wrapper tag: 'div', class: 'col-sm-9 input-group' do |input|
105
+ input.use :input, class: 'form-control'
106
+ input.use :hint, wrap_with: { tag: 'span', class: 'help-block' }
107
+ input.use :error, wrap_with: { tag: 'p', class: 'help-inline' }
108
+ end
109
+ end
110
+
111
+ config.wrappers :horizontal_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
112
+ b.use :html5
113
+ b.use :placeholder
114
+ b.use :label, class: 'col-sm-3 control-label'
115
+
116
+ b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
117
+ ba.use :input, class: 'form-control'
118
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
119
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
120
+ end
121
+ end
122
+
123
+ config.wrappers :horizontal_file_input, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
124
+ b.use :html5
125
+ b.use :placeholder
126
+ b.use :label, class: 'col-sm-3 control-label'
127
+
128
+ b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
129
+ ba.use :input
130
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
131
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
132
+ end
133
+ end
134
+
135
+ config.wrappers :horizontal_boolean, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
136
+ b.use :html5
137
+ b.use :placeholder
138
+
139
+ b.wrapper tag: 'div', class: 'col-sm-offset-3 col-sm-9' do |wr|
140
+ wr.wrapper tag: 'div', class: 'checkbox' do |ba|
141
+ ba.use :label_input, class: 'col-sm-9'
142
+ end
143
+
144
+ wr.use :error, wrap_with: { tag: 'span', class: 'help-block' }
145
+ wr.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
146
+ end
147
+ end
148
+
149
+ config.wrappers :horizontal_radio_and_checkboxes, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
150
+ b.use :html5
151
+ b.use :placeholder
152
+
153
+ b.use :label, class: 'col-sm-3 control-label'
154
+
155
+ b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
156
+ ba.use :input
157
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
158
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
159
+ end
160
+ end
161
+
162
+ # Wrappers for forms and inputs using the Bootstrap toolkit.
163
+ # Check the Bootstrap docs (http://getbootstrap.com)
164
+ # to learn about the different styles for forms and inputs,
165
+ # buttons and other elements.
166
+ config.default_wrapper = :vertical_form
167
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ Haystack::Engine.routes.draw do
2
+ resources :searches, :only => [:new, :create]
3
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Generates a concrete searcher model and the relevant views
3
+
4
+ Example:
5
+ rails generate searcher ModelName
6
+
7
+ This will create:
8
+ app/searchers/model_name_searcher.rb
@@ -0,0 +1,17 @@
1
+ class SearcherGenerator < Rails::Generators::NamedBase
2
+ source_root File.expand_path('../templates', __FILE__)
3
+
4
+ def create_searcher_model
5
+
6
+ empty_directory File.join("app", "searchers")
7
+ model_names.each do |name|
8
+ template "searcher_template.rb", File.join("app","searchers", "#{name}_searcher.rb")
9
+ end
10
+ end
11
+
12
+
13
+ private
14
+ def model_names
15
+ ARGV.map(&:underscore)
16
+ end
17
+ end
@@ -0,0 +1,45 @@
1
+ ###############################################################################
2
+ # <%= name.camelize %>Searcher: Searches over your <%= name.camelize %> Model
3
+ #
4
+ ###############################################################################
5
+ class <%= name.camelize %>Searcher < Haystack::BaseSearcher
6
+
7
+ BASE = <%= name.camelize %>
8
+
9
+ #############################################################################
10
+ # SEARCHABLE FIELDS: uncomment `attr_accessor` below and define any model
11
+ # attributes you would like to search over
12
+ # attr_accessor
13
+ #
14
+ ###############################################################################
15
+
16
+
17
+ # Haystack uses rails' understanding of classes
18
+
19
+ protected
20
+
21
+ #----------------------------------------------------------------------------
22
+ # Simple Equality Queries
23
+ # Wherever simple equality is acceptable (e.g. "id = 7", "id in (4,5)")
24
+ # the searcher handles this out of the box
25
+ #----------------------------------------------------------------------------
26
+
27
+ #----------------------------------------------------------------------------
28
+ # Inequality Queries
29
+ # Most commonly dates and dollar values, add any methods here which search
30
+ # based on an inequality (e.g. "cash_value < 10000")
31
+ #----------------------------------------------------------------------------
32
+
33
+ #----------------------------------------------------------------------------
34
+ # Boolean Queries
35
+ # Not checking a box does not equal "restrict to things where this is false"
36
+ #----------------------------------------------------------------------------
37
+
38
+ #----------------------------------------------------------------------------
39
+ # Custom Queries
40
+ # When search logic doesn't fall into the above categories, place logic below
41
+ #----------------------------------------------------------------------------
42
+
43
+
44
+
45
+ end
@@ -0,0 +1,9 @@
1
+ require 'simple_form'
2
+ require 'haml-rails'
3
+
4
+ module Haystack
5
+ class Engine < ::Rails::Engine
6
+ isolate_namespace Haystack
7
+ config.autoload_paths += %W(#{Rails.root}/app/searchers)
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module Haystack
2
+ VERSION = "1.0.0"
3
+ end
data/lib/haystack.rb ADDED
@@ -0,0 +1,4 @@
1
+ require "haystack/engine"
2
+
3
+ module Haystack
4
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :haystack do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: haystack
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Aaron Magil
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.1'
27
+ description: Haystack is based on work by Julian Ray and Aaron Magil for Cambridge
28
+ Systematics TransAM.
29
+ email:
30
+ - amagil@camsys.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - MIT-LICENSE
36
+ - README.md
37
+ - Rakefile
38
+ - app/assets/javascripts/haystack/application.js
39
+ - app/assets/stylesheets/haystack/application.css
40
+ - app/controllers/haystack/application_controller.rb
41
+ - app/controllers/haystack/searches_controller.rb
42
+ - app/helpers/haystack/application_helper.rb
43
+ - app/helpers/haystack/searches_helper.rb
44
+ - app/models/haystack/base_searcher.rb
45
+ - app/views/layouts/haystack/application.html.erb
46
+ - config/initializers/simple_form.rb
47
+ - config/initializers/simple_form_bootstrap.rb
48
+ - config/routes.rb
49
+ - lib/generators/searcher/USAGE
50
+ - lib/generators/searcher/searcher_generator.rb
51
+ - lib/generators/searcher/templates/searcher_template.rb
52
+ - lib/haystack.rb
53
+ - lib/haystack/engine.rb
54
+ - lib/haystack/version.rb
55
+ - lib/tasks/haystack_tasks.rake
56
+ homepage: https://github.com/abmagil/haystack
57
+ licenses:
58
+ - MIT
59
+ metadata: {}
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 2.2.2
77
+ signing_key:
78
+ specification_version: 4
79
+ summary: A Simple Searcher
80
+ test_files: []
81
+ has_rdoc: