effective_search 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1907a521e17551feb703f0d350f20ba41e469c09eb9656f0a6239d0d384e18d3
4
+ data.tar.gz: 8ca68586517e83bfa7248648ffaaf45c2346233960e8029c9fb6e6be4a8b4e73
5
+ SHA512:
6
+ metadata.gz: 2da6d275023622322be29cfa0e76af087a8921a98d07b1c2831d8728d707370bffece6d39addb15bcefa01844117bd2711b54fe852b143dd9326a54117dbec89
7
+ data.tar.gz: bd50a2bbd2ca84e9c5c4c067cde0460b76c8ef41da8bdc703fccbcc35c907a10743dd12482f3d761b41e7456ba039ee169616d61723005f2d65b981b78002fb5
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2024 Code and Effect Inc.
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,106 @@
1
+ # Effective Search
2
+
3
+ Search posts, pages, permalinks and events.
4
+
5
+ ## Getting Started
6
+
7
+ This requires Rails 6+ and Twitter Bootstrap 4 and just works with Devise.
8
+
9
+ Please first install the [effective_datatables](https://github.com/code-and-effect/effective_datatables) gem.
10
+
11
+ Please download and install the [Twitter Bootstrap4](http://getbootstrap.com)
12
+
13
+ Add to your Gemfile:
14
+
15
+ ```ruby
16
+ gem 'haml'
17
+ gem 'pg_search'
18
+ gem 'effective_search'
19
+ ```
20
+
21
+ Run the bundle command to install it:
22
+
23
+ ```console
24
+ bundle install
25
+ ```
26
+
27
+ Then run the generator:
28
+
29
+ ```ruby
30
+ rails generate effective_search:install
31
+ ```
32
+
33
+ The generator will install an initializer which describes all configuration options and creates a database migration.
34
+
35
+ If you want to tweak the table names, manually adjust both the configuration file and the migration now.
36
+
37
+ Then migrate the database:
38
+
39
+ ```ruby
40
+ rake db:migrate
41
+ ```
42
+
43
+ ## Configuration
44
+
45
+ Change the `config/initializers/effective_search.rb` class name. Then you can use a custom search class:
46
+
47
+ ```
48
+ module Example
49
+ class Search
50
+ include EffectiveSearchSearch
51
+
52
+ def per_page
53
+ 3
54
+ end
55
+
56
+ end
57
+ end
58
+ ```
59
+
60
+ By default it will search any `PgSearch::Document` resources.
61
+
62
+ So to add your own custom search class, add
63
+
64
+ ```
65
+ include PgSearch::Model
66
+ multisearchable against: [:body]
67
+ ```
68
+
69
+ to your class and it should flow through to the search automatically.
70
+
71
+ You can customize the search class `def path()` method if needed.
72
+
73
+ ## Authorization
74
+
75
+ All authorization checks are handled via the effective_resources gem found in the `config/initializers/effective_resources.rb` file.
76
+
77
+ ## Permissions
78
+
79
+ The permissions you actually want to define are as follows (using CanCan):
80
+
81
+ ```ruby
82
+ can(:index, EffectiveSearch.Search) # The /search page
83
+ ```
84
+
85
+ Each searchable result object will get run through `EffectiveResources.authorize?` before being rendered
86
+
87
+ ## License
88
+
89
+ MIT License. Copyright [Code and Effect Inc.](http://www.codeandeffect.com/)
90
+
91
+ ## Testing
92
+
93
+ Run tests by:
94
+
95
+ ```ruby
96
+ rails test
97
+ ```
98
+
99
+ ## Contributing
100
+
101
+ 1. Fork it
102
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
103
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
104
+ 4. Push to the branch (`git push origin my-new-feature`)
105
+ 5. Bonus points for test coverage
106
+ 6. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
9
+
10
+ require "rake/testtask"
11
+
12
+ Rake::TestTask.new(:test) do |t|
13
+ t.libs << 'test'
14
+ t.pattern = 'test/**/*_test.rb'
15
+ t.verbose = false
16
+ end
17
+
18
+ task default: :test
@@ -0,0 +1,3 @@
1
+ //= link_directory ../javascripts .js
2
+ //= link_directory ../stylesheets .css
3
+ //= link_tree ../images
File without changes
@@ -0,0 +1 @@
1
+ //= require_tree ./effective_search
@@ -0,0 +1,31 @@
1
+ // This is the Search#index page
2
+ // This should be a div. The body tag also gets .effective-search on Search#index page only
3
+ div.effective-search {
4
+ input#q_term {
5
+ font-size: 1rem;
6
+ background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 28.5 28.5'%3E%3Cpath d='M76.063,73.639,69.6,67.178A12.009,12.009,0,1,0,67.178,69.6l6.461,6.461a1.717,1.717,0,0,0,2.424-2.424ZM51.428,60A8.57,8.57,0,1,1,60,68.567,8.57,8.57,0,0,1,51.428,60Z' transform='translate(-48 -48)' fill='%230058a4'/%3E%3C/svg%3E");
7
+ background-repeat: no-repeat;
8
+ background-position: calc(100% - 0.75rem) center !important;
9
+ }
10
+
11
+ .search-result {
12
+ margin-bottom: 1.5rem;
13
+
14
+ // mark { }
15
+ //.search-title { }
16
+ //.search-link { }
17
+ //.search-body { }
18
+ }
19
+ }
20
+
21
+ // The nav item search bar
22
+ .effective-search-nav-item {
23
+ input {
24
+ width: 250px;
25
+
26
+ font-size: 1rem;
27
+ background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 28.5 28.5'%3E%3Cpath d='M76.063,73.639,69.6,67.178A12.009,12.009,0,1,0,67.178,69.6l6.461,6.461a1.717,1.717,0,0,0,2.424-2.424ZM51.428,60A8.57,8.57,0,1,1,60,68.567,8.57,8.57,0,0,1,51.428,60Z' transform='translate(-48 -48)' fill='%230058a4'/%3E%3C/svg%3E");
28
+ background-repeat: no-repeat;
29
+ background-position: calc(100% - 0.75rem) center !important;
30
+ }
31
+ }
@@ -0,0 +1 @@
1
+ @import 'effective_search/base';
@@ -0,0 +1,41 @@
1
+ module Effective
2
+ class SearchController < ApplicationController
3
+ if defined?(Devise)
4
+ before_action(:authenticate_user!, if: -> { EffectiveSearch.authenticate_user? })
5
+ end
6
+
7
+ include Effective::CrudController
8
+
9
+ def index
10
+ EffectiveResources.authorize!(self, :index, EffectiveSearch.Search)
11
+
12
+ # But more often we do a full membership directory search screen
13
+ @search = build_search
14
+ @search.search!
15
+
16
+ if @search.present?
17
+ @page_title = "Search results for &lsquo;#{@search}&rsquo;".html_safe
18
+ else
19
+ @page_title = "Search"
20
+ end
21
+ end
22
+
23
+ def build_search
24
+ search = EffectiveSearch.Search.new(search_params)
25
+ search.current_user = current_user
26
+ search.view_context = view_context
27
+ search
28
+ end
29
+
30
+ def search_params
31
+ return {} unless params[:q].present?
32
+
33
+ if params[:q].respond_to?(:to_h) # From the search form
34
+ params.require(:q).permit!
35
+ else
36
+ { term: params.permit(:q).fetch(:q) } # From the url /directory?q=asdf
37
+ end
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,9 @@
1
+ module EffectiveSearchHelper
2
+
3
+ def effective_search_nav_item
4
+ if EffectiveResources.authorized?(self, :index, EffectiveSearch.Search)
5
+ render('effective/search/form_nav_item')
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,150 @@
1
+ # frozen_string_literal: true
2
+
3
+ # EffectiveSearchSearch
4
+ # Mark your search model with include EffectiveSearchSearch
5
+
6
+ module EffectiveSearchSearch
7
+ extend ActiveSupport::Concern
8
+
9
+ module ClassMethods
10
+ def effective_search_search?; true; end
11
+ end
12
+
13
+ included do
14
+ include ActiveModel::Model
15
+
16
+ attr_accessor :current_user
17
+ attr_accessor :view_context
18
+
19
+ attr_accessor :term
20
+ validates :term, length: { minimum: 3, allow_blank: true }
21
+ end
22
+
23
+ def to_s
24
+ term.to_s
25
+ end
26
+
27
+ # Limit the search to certain searchable types. Return nil for all
28
+ # ['Effective::Page', 'Effective::Post']
29
+ def searchable_types
30
+ nil
31
+ end
32
+
33
+ def per_page
34
+ 24
35
+ end
36
+
37
+ def present?
38
+ term.present?
39
+ end
40
+
41
+ # Search and assigns the collection
42
+ # Assigns the entire collection() if there are no search terms
43
+ # Otherwise validate the search terms
44
+ def search!
45
+ @search_results = build_collection()
46
+ @search_results = @search_results.none if present? && !valid?
47
+ @search_results
48
+ end
49
+
50
+ # The unpaginated results of the search
51
+ def search_results
52
+ @search_results || []
53
+ end
54
+
55
+ # The paginated results
56
+ def results(page: nil)
57
+ page = (page || 1).to_i
58
+ offset = [(page - 1), 0].max * per_page
59
+
60
+ search_results.limit(per_page).offset(offset)
61
+ end
62
+
63
+ # View helper
64
+ def authorized?(result)
65
+ raise('expected a PgSearch::Document') unless result.kind_of?(PgSearch::Document)
66
+
67
+ searchable = result.searchable
68
+
69
+ return false if searchable.blank?
70
+ return false if searchable.try(:draft?)
71
+ return false if searchable.try(:archived?)
72
+
73
+ if view_context.present?
74
+ return EffectiveResources.authorized?(view_context, :show, searchable)
75
+ end
76
+
77
+ true
78
+ end
79
+
80
+ # View helper
81
+ def title(result)
82
+ (result.try(:searchable).try(:title) || result.to_s).html_safe
83
+ end
84
+
85
+ # View helper
86
+ def path(result)
87
+ effective_path(result) || polymorphic_path(result) || raise("unknown path for #{result.searchable_type}")
88
+ end
89
+
90
+ # View helper
91
+ def body(result)
92
+ content = result.try(:pg_search_highlight) || result.to_s
93
+ scrubs.each { |pattern| content.gsub!(pattern, '') }
94
+ content.html_safe
95
+ end
96
+
97
+ # Scrub the body content with these regexes
98
+ def scrubs
99
+ [
100
+ /(<p>)?\[posts\scategory=\"(.*?)\"\](<\/p>)?/,
101
+ /(<p>)?\[permalinks\stag=\"(.*?)\"\](<\/p>)?/,
102
+ /\[picflow\s+gallery="[^"]*"\]/
103
+ ]
104
+ end
105
+
106
+ protected
107
+
108
+ # Returns an ActiveRecord collection of PgSearch::Document
109
+ def build_collection
110
+ raise('expected pg_search gem') unless defined?(PgSearch)
111
+
112
+ collection = PgSearch::Document.all
113
+
114
+ if term.present?
115
+ collection = PgSearch.multisearch(term)
116
+ end
117
+
118
+ # Restrict search to certain searchable types
119
+ if searchable_types.present?
120
+ collection = collection.where(searchable_type: searchable_types)
121
+ end
122
+
123
+ # Preload what we need
124
+ collection = collection.includes(searchable: [:rich_text_body])
125
+
126
+ # Return all the results
127
+ collection
128
+ end
129
+
130
+ # Sort of a view helper. The result is passed through here
131
+ def effective_path(result)
132
+ case result.searchable_type
133
+ when 'Effective::Page'
134
+ EffectivePages::Engine.routes.url_helpers.page_path(result.searchable)
135
+ when 'Effective::Permalink'
136
+ EffectivePages::Engine.routes.url_helpers.permalink_redirect_path(result.searchable)
137
+ when 'Effective::Post'
138
+ EffectivePosts::Engine.routes.url_helpers.post_path(result.searchable)
139
+ when 'Effective::Event'
140
+ EffectiveEvents::Engine.routes.url_helpers.event_path(result.searchable)
141
+ end
142
+ end
143
+
144
+ def polymorphic_path(result)
145
+ url_helpers = (defined?(Tenant) ? Tenant.routes : Rails.application.routes.url_helpers)
146
+ url_helpers.try("#{result.searchable_type.underscore}_path", result.searchable)
147
+ end
148
+
149
+ end
150
+
@@ -0,0 +1,5 @@
1
+ module Effective
2
+ class Search
3
+ include EffectiveSearchSearch
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ = effective_form_with(scope: :q, model: search, method: :get, url: effective_search.search_path) do |f|
2
+ = f.text_field :term, label: 'Search'
3
+
4
+ = f.save('Search', class: 'btn btn-primary btn-search mr-3', name: nil)
5
+ = link_to 'Reset', request.path
@@ -0,0 +1,3 @@
1
+ %li.nav-item.effective-search-nav-item
2
+ = effective_form_with(scope: :q, model: EffectiveSearch.Search.new, method: :get, url: effective_search.search_path, layout: :inline) do |f|
3
+ = f.text_field :term, label: false, placeholder: 'Search', autofocus: false, id: nil
@@ -0,0 +1,2 @@
1
+ .effective-search
2
+ = yield
@@ -0,0 +1,9 @@
1
+ .search-result
2
+ - title = search.title(result)
3
+ - path = search.path(result)
4
+
5
+ %h4.search-title
6
+ = link_to(title, path, title: title)
7
+
8
+ = link_to (root_url.chomp('/') + path), path, class: 'search-link'
9
+ .search-body= search.body(result)
@@ -0,0 +1,17 @@
1
+ = render 'layout' do
2
+ = render('effective/search/form', search: search)
3
+
4
+ - if search.present?
5
+ %hr
6
+
7
+ - results = search.results(page: params[:page])
8
+
9
+ - if results.length == 0
10
+ .alert.alert-info There are no results for your search. Please try again.
11
+
12
+ - if results.length > 0
13
+ - collection = results.with_pg_search_highlight.select { |result| search.authorized?(result) }
14
+ = render(collection: collection, partial: 'effective/search/result', locals: { search: search })
15
+
16
+ %nav.d-flex.justify-content-center
17
+ = bootstrap_paginate(results, per_page: search.per_page)
@@ -0,0 +1 @@
1
+ = render('effective/search/search', search: @search)
@@ -0,0 +1,14 @@
1
+ EffectiveSearch.setup do |config|
2
+ # Layout Settings
3
+ # Configure the Layout per controller, or all at once
4
+ # config.layout = { application: 'application', admin: 'admin' }
5
+
6
+ # Search Settings
7
+ # Configure the class responsible for the search.
8
+ # This should declare effective_search_search
9
+ # config.search_class_name = 'Effective::Search'
10
+
11
+ # Authenticate User
12
+ # Will require sign in to view the search page
13
+ # config.authenticate_user = false
14
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ Rails.application.routes.draw do
4
+ mount EffectiveSearch::Engine => '/', as: 'effective_search'
5
+ end
6
+
7
+ EffectiveSearch::Engine.routes.draw do
8
+ # Public routes
9
+ scope module: 'effective' do
10
+ match '/search', to: 'search#index', via: [:get], as: :search
11
+ end
12
+
13
+ namespace :admin do
14
+ end
15
+
16
+ end
@@ -0,0 +1,25 @@
1
+ class CreateEffectiveSearch < ActiveRecord::Migration[7.0]
2
+ def up
3
+ # PgSearch trigram extension
4
+ if defined?(Postgres)
5
+ enable_extension('pg_trgm') unless extension_enabled?('pg_trgm')
6
+ end
7
+
8
+ # PgSearch multisearch table
9
+ create_table :pg_search_documents, if_not_exists: true do |t|
10
+ t.text :content
11
+ t.belongs_to :searchable, polymorphic: true, index: true
12
+ t.timestamps null: false
13
+ end
14
+ end
15
+
16
+ def down
17
+ # PgSearch trigram extension
18
+ if defined?(Postgres)
19
+ disable_extension('pg_trgm') if extension_enabled?('pg_trgm')
20
+ end
21
+
22
+ # PgSearch multisearch table
23
+ drop_table :pg_search_documents, if_exists: true
24
+ end
25
+ end
data/db/seeds.rb ADDED
@@ -0,0 +1 @@
1
+ puts "Running effective_search seeds"
@@ -0,0 +1,11 @@
1
+ module EffectiveSearch
2
+ class Engine < ::Rails::Engine
3
+ engine_name 'effective_search'
4
+
5
+ # Set up our default configuration options.
6
+ initializer 'effective_search.defaults', before: :load_config_initializers do |app|
7
+ eval File.read("#{config.root}/config/effective_search.rb")
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module EffectiveSearch
2
+ VERSION = '0.1.0'.freeze
3
+ end
@@ -0,0 +1,21 @@
1
+ require 'effective_resources'
2
+ require 'effective_search/engine'
3
+ require 'effective_search/version'
4
+
5
+ module EffectiveSearch
6
+
7
+ def self.config_keys
8
+ [:search_class_name, :authenticate_user, :layout]
9
+ end
10
+
11
+ include EffectiveGem
12
+
13
+ def self.Search
14
+ search_class_name&.constantize || Effective::Search
15
+ end
16
+
17
+ def self.authenticate_user?
18
+ authenticate_user == true
19
+ end
20
+
21
+ end
@@ -0,0 +1,30 @@
1
+ module EffectiveSearch
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ include Rails::Generators::Migration
5
+
6
+ desc 'Creates an EffectiveSearch initializer in your application.'
7
+
8
+ source_root File.expand_path('../../templates', __FILE__)
9
+
10
+ def self.next_migration_number(dirname)
11
+ if not ActiveRecord::Base.timestamped_migrations
12
+ Time.new.utc.strftime("%Y%m%d%H%M%S")
13
+ else
14
+ '%.3d' % (current_migration_number(dirname) + 1)
15
+ end
16
+ end
17
+
18
+ def copy_initializer
19
+ template ('../' * 3) + 'config/effective_search.rb', 'config/initializers/effective_search.rb'
20
+ end
21
+
22
+ def create_migration_file
23
+ @search_table_name = ':' + EffectiveSearch.search_table_name.to_s
24
+
25
+ migration_template ('../' * 3) + 'db/migrate/101_create_effective_search.rb', 'db/migrate/create_effective_search.rb'
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,8 @@
1
+ namespace :effective_search do
2
+
3
+ # bundle exec rake effective_search:seed
4
+ task seed: :environment do
5
+ load "#{__dir__}/../../db/seeds.rb"
6
+ end
7
+
8
+ end
metadata ADDED
@@ -0,0 +1,210 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: effective_search
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Code and Effect
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-12-06 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: 6.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: 6.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: pg_search
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: effective_bootstrap
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: effective_resources
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: devise
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: haml-rails
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry-byebug
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: effective_test_bot
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: effective_developer
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: Search effective events pages and posts with pg_search
154
+ email:
155
+ - info@codeandeffect.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - MIT-LICENSE
161
+ - README.md
162
+ - Rakefile
163
+ - app/assets/config/effective_search_manifest.js
164
+ - app/assets/javascripts/effective_search.js
165
+ - app/assets/javascripts/effective_search/base.js
166
+ - app/assets/stylesheets/effective_search.scss
167
+ - app/assets/stylesheets/effective_search/base.scss
168
+ - app/controllers/effective/search_controller.rb
169
+ - app/helpers/effective_search_helper.rb
170
+ - app/models/concerns/effective_search_search.rb
171
+ - app/models/effective/search.rb
172
+ - app/views/effective/search/_form.html.haml
173
+ - app/views/effective/search/_form_nav_item.html.haml
174
+ - app/views/effective/search/_layout.html.haml
175
+ - app/views/effective/search/_result.html.haml
176
+ - app/views/effective/search/_search.html.haml
177
+ - app/views/effective/search/index.html.haml
178
+ - config/effective_search.rb
179
+ - config/routes.rb
180
+ - db/migrate/101_create_effective_search.rb
181
+ - db/seeds.rb
182
+ - lib/effective_search.rb
183
+ - lib/effective_search/engine.rb
184
+ - lib/effective_search/version.rb
185
+ - lib/generators/effective_search/install_generator.rb
186
+ - lib/tasks/effective_search_tasks.rake
187
+ homepage: https://github.com/code-and-effect/effective_search
188
+ licenses:
189
+ - MIT
190
+ metadata: {}
191
+ post_install_message:
192
+ rdoc_options: []
193
+ require_paths:
194
+ - lib
195
+ required_ruby_version: !ruby/object:Gem::Requirement
196
+ requirements:
197
+ - - ">="
198
+ - !ruby/object:Gem::Version
199
+ version: '0'
200
+ required_rubygems_version: !ruby/object:Gem::Requirement
201
+ requirements:
202
+ - - ">="
203
+ - !ruby/object:Gem::Version
204
+ version: '0'
205
+ requirements: []
206
+ rubygems_version: 3.5.6
207
+ signing_key:
208
+ specification_version: 4
209
+ summary: Search effective events pages and posts with pg_search
210
+ test_files: []