alchemy-pg_search 4.2.0 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b24390ba290061c913ce244c49cf38352d303bbd50e0855d2144517105ce6b53
4
- data.tar.gz: 963ed8b25276155ce526186eb07b12b8d616b60df0d0d98100c713ed12eddc1c
3
+ metadata.gz: efbd69f49a2b6dd894da769c73bf8336f257d14f1c59b5a6ec3e45cc1f01ba45
4
+ data.tar.gz: 30712617a4a1142d232da68753c74a71b86c6c9fa8904bca03b461ff980c1fd4
5
5
  SHA512:
6
- metadata.gz: 3acc723b3ae261ae52de6c1d59a6e2f727d870bb6849aa8ec461dd2eceaa8578cbc45df4562b5820316ff948210395921287b8391dc675ddaef8448012c980a9
7
- data.tar.gz: b203d53773796999d6f04fd27c8834121e872f359342eeec9cf97737cd487ddae1505f3df8c5f3c83793d9b406ad13f7f88ca1d184d8b1bf72f0d5600c6eb4ea
6
+ metadata.gz: 52d1d223c67ce3edea17aa2c9ab81858102abe50d0e61b8bdf58b48bf208e6ff46914e76dd766bf5b506f1b0e9a374eb341a8638680f972eaf0bbf5022f5531b
7
+ data.tar.gz: 36b0f2f6fe63cd2a77d2a719d62f80e5f1e09944ed67944304c0017e157f5789ca6bf24803f0891f9a81d6dee332a0d10af9784a195b334ac0b5b6fbf643943b
@@ -9,7 +9,7 @@ jobs:
9
9
  RAILS_ENV: test
10
10
  services:
11
11
  postgres:
12
- image: postgres:11
12
+ image: postgres:12
13
13
  env:
14
14
  POSTGRES_USER: postgres
15
15
  POSTGRES_PASSWORD: password
@@ -21,7 +21,7 @@ jobs:
21
21
  - name: Set up Ruby
22
22
  uses: ruby/setup-ruby@v1
23
23
  with:
24
- ruby-version: 2.7
24
+ ruby-version: 3.2
25
25
  bundler-cache: true
26
26
  - name: Prepare database
27
27
  run: bundle exec rake alchemy:spec:prepare
data/.gitignore CHANGED
@@ -6,6 +6,8 @@ Gemfile.lock
6
6
  spec/dummy/log/*.log
7
7
  spec/dummy/db/*.sqlite3*
8
8
  spec/dummy/tmp/*
9
+ spec/dummy/public/*
10
+ spec/dummy/uploads/*
9
11
  .ruby-*
10
12
  node_modules
11
13
  yarn.lock
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## [v5.1.0](https://github.com/AlchemyCMS/alchemy-pg_search/tree/v5.1.0) (2023-12-20)
4
+
5
+ [Full Changelog](https://github.com/AlchemyCMS/alchemy-pg_search/compare/v5.0.0...v5.1.0)
6
+
7
+ **Merged pull requests:**
8
+
9
+ - Improve search speed [\#42](https://github.com/AlchemyCMS/alchemy-pg_search/pull/42) ([sascha-karnatz](https://github.com/sascha-karnatz))
10
+ - Make migrations more error tolerant [\#41](https://github.com/AlchemyCMS/alchemy-pg_search/pull/41) ([sascha-karnatz](https://github.com/sascha-karnatz))
11
+
12
+ ## [v5.0.0](https://github.com/AlchemyCMS/alchemy-pg_search/tree/v5.0.0) (2023-09-01)
13
+
14
+ [Full Changelog](https://github.com/AlchemyCMS/alchemy-pg_search/compare/v4.2.0...v5.0.0)
15
+
16
+ **Merged pull requests:**
17
+
18
+ - Update to Alchemy 7.0 [\#39](https://github.com/AlchemyCMS/alchemy-pg_search/pull/39) ([sascha-karnatz](https://github.com/sascha-karnatz))
19
+
3
20
  ## [v4.2.0](https://github.com/AlchemyCMS/alchemy-pg_search/tree/v4.2.0) (2023-01-23)
4
21
 
5
22
  [Full Changelog](https://github.com/AlchemyCMS/alchemy-pg_search/compare/v4.1.1...v4.2.0)
data/Gemfile CHANGED
@@ -2,13 +2,11 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem "rails", "~> 6.0.0"
6
- ENV.fetch("ALCHEMY_BRANCH", "6.1-stable").tap do |branch|
7
- gem "alchemy_cms", github: "AlchemyCMS/alchemy_cms", branch: branch
8
- end
5
+ gem "rails", "~> 7.0.0"
6
+ gem "alchemy_cms", "~> 7.0.0"
7
+
9
8
  gem "sassc-rails"
10
9
  gem "sassc", "~> 2.4.0"
11
- gem "webpacker"
12
10
  gem "pg", "~> 1.0"
13
11
  gem "puma"
14
12
 
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014, magic labs GmbH
1
+ Copyright (c) Blish GmbH
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without modification,
data/README.md CHANGED
@@ -4,6 +4,12 @@
4
4
 
5
5
  This gem provides full text search for projects using postgresql databases to Alchemy CMS 6.0 and above.
6
6
 
7
+ ## Requirements
8
+
9
+ * Ruby 3.0 or newer
10
+ * Alchemy CMS 7.0 or newer
11
+ * PostgreSQL 12.x or newer
12
+
7
13
  ## Installation
8
14
 
9
15
  Add this line to your application's `Gemfile`:
@@ -24,9 +30,15 @@ Run install script:
24
30
  $ bin/rails g alchemy:pg_search:install
25
31
  ```
26
32
 
33
+ > [!NOTE]
34
+ > The installation will generate an autogenerated column which can be configured with a language. The default
35
+ > value should work for the most languages. If you wish to change this behavior you should add
36
+ > the `Alchemy::PgSearch.config`
37
+ > into the project initializer before running the install script. (See [Configure Behavior](#configure-behavior))
38
+
27
39
  ## Usage
28
40
 
29
- Every `EssenceText`, `EssenceRichtext` and `EssencePicture` will be indexed unless you tell Alchemy to not index a specific content.
41
+ Every `Ingredient` will be indexed unless you tell Alchemy to not index a specific content.
30
42
 
31
43
  ### Disable Indexing
32
44
 
@@ -51,7 +63,7 @@ Pass `searchable: false` to your element definitions and Alchemy will not index
51
63
  - name: secret_sauce
52
64
  searchable: false
53
65
  ingredients:
54
- - name: sauce
66
+ - role: sauce
55
67
  type: Text
56
68
  default: 'This is my secret sauce.'
57
69
  ```
@@ -63,9 +75,9 @@ Pass `searchable: false` to your content definitions and Alchemy will not index
63
75
  ```yaml
64
76
  # elements.yml
65
77
  - name: secrets
66
- contents:
67
- - name: passwords
68
- type: EssenceText
78
+ ingredients:
79
+ - role: passwords
80
+ type: Text
69
81
  searchable: false
70
82
  default: 'This is my secret password.'
71
83
  ```
@@ -76,7 +88,7 @@ The same works for `ingredients` as well
76
88
  # elements.yml
77
89
  - name: secrets
78
90
  ingredients:
79
- - name: passwords
91
+ - role: passwords
80
92
  type: Text
81
93
  searchable: false
82
94
  default: 'This is my secret password.'
@@ -88,10 +100,16 @@ Configure the gem in an initializer. The default configurations are:
88
100
 
89
101
  ```ruby
90
102
  Alchemy::PgSearch.config = {
91
- paginate_per: 10, # amount of results per page
103
+ dictionary: 'simple',
104
+ paginate_per: 10
92
105
  }
93
106
  ```
94
107
 
108
+ Configuration Name | Default Value | Description
109
+ --------------------|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
110
+ dictionary | simple | Dictionary for the multisearch tsearch - config, which is used to find the content. The dictionary can impact the amout found documents, because it removes language specific stop words. See more in the [PostgreSQL documentation](https://www.postgresql.org/docs/current/textsearch-dictionaries.html).
111
+ paginate_per | 10 | Amount of results per page. The value can be set to `nil` to disable the pagination.
112
+
95
113
  You can also overwrite the default multisearch configuration to use other search strategies. For more information take
96
114
  a look into the [PgSearch Readme](https://github.com/Casecommons/pg_search#configuring-multi-search).
97
115
 
@@ -107,7 +125,8 @@ end
107
125
 
108
126
  ### Rendering search results.
109
127
 
110
- In order to render the search results, you'll need a page layout that represents the search result page. Simply mark a page layout as `searchresults: true`. The search form will pick this page as result page.
128
+ In order to render the search results, you'll need a page layout that represents the search result page. Simply mark a
129
+ page layout as `searchresults: true`. The search form will pick this page as result page.
111
130
 
112
131
  #### Search Results Page
113
132
 
@@ -118,7 +137,8 @@ In order to render the search results, you'll need a page layout that represents
118
137
  unique: true
119
138
  ```
120
139
 
121
- Tip: For maximum flexibility you could also add an element that represents the search results. This lets your editors to place additional elements (maybe a header image or additional text blocks) on the search result page.
140
+ Tip: For maximum flexibility you could also add an element that represents the search results. This lets your editors to
141
+ place additional elements (maybe a header image or additional text blocks) on the search result page.
122
142
 
123
143
  ```yaml
124
144
  # page_layouts.yml
@@ -126,16 +146,17 @@ Tip: For maximum flexibility you could also add an element that represents the s
126
146
  searchresults: true
127
147
  unique: true
128
148
  elements:
129
- - searchresults
149
+ - searchresults
130
150
  autogenerate:
131
- - searchresults
151
+ - searchresults
132
152
 
133
153
  # elements.yml
134
154
  - name: searchresults
135
155
  unique: true
136
156
  ```
137
157
 
138
- and then use the view helpers to render the search form on the page layout partial and the search results on the element view partial.
158
+ and then use the view helpers to render the search form on the page layout partial and the search results on the element
159
+ view partial.
139
160
 
140
161
  ### View Helpers
141
162
 
@@ -12,11 +12,13 @@ Gem::Specification.new do |spec|
12
12
  spec.summary = "This gem provides PostgreSQL full text search to Alchemy"
13
13
  spec.homepage = "https://alchemy-cms.com"
14
14
  spec.license = "BSD-3-Clause"
15
+ spec.required_ruby_version = ">= 3.0.0"
16
+ spec.requirements << 'PostgreSQL >= 12.x'
15
17
 
16
18
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^spec/}) }
17
19
  spec.require_paths = ["lib"]
18
20
 
19
- spec.add_runtime_dependency "alchemy_cms", [">= 6.1", "< 7"]
21
+ spec.add_runtime_dependency "alchemy_cms", [">= 7.0", "< 8"]
20
22
  spec.add_runtime_dependency "pg_search", ["~> 2.1"]
21
23
  spec.add_runtime_dependency "pg"
22
24
 
@@ -1,13 +1,18 @@
1
1
  module Alchemy::PgSearch::IngredientExtension
2
- def self.prepended(base)
3
- base.include PgSearch::Model
4
- base.multisearchable(
2
+
3
+ def self.multisearch_config
4
+ {
5
5
  against: [
6
6
  :value,
7
7
  ],
8
8
  additional_attributes: ->(ingredient) { { page_id: ingredient.element.page.id } },
9
- if: :searchable?,
10
- )
9
+ if: :searchable?
10
+ }
11
+ end
12
+
13
+ def self.prepended(base)
14
+ base.include PgSearch::Model
15
+ base.multisearchable(multisearch_config)
11
16
  end
12
17
 
13
18
  def searchable?
@@ -17,4 +22,8 @@ module Alchemy::PgSearch::IngredientExtension
17
22
  end
18
23
  end
19
24
 
25
+ # add the PgSearch model to all ingredients
20
26
  Alchemy::Ingredient.prepend(Alchemy::PgSearch::IngredientExtension)
27
+
28
+ # only enable the search for Text, Richtext, and Picture
29
+ Alchemy::Ingredients::Picture.multisearchable(Alchemy::PgSearch::IngredientExtension.multisearch_config.merge({against: [:caption]}))
@@ -1,5 +1,5 @@
1
- class AddSearchableToAlchemyEssenceTexts < ActiveRecord::Migration[5.1]
1
+ class AddSearchableToAlchemyEssenceTexts < ActiveRecord::Migration[6.1]
2
2
  def change
3
- add_column :alchemy_essence_texts, :searchable, :boolean, default: true
3
+ add_column :alchemy_essence_texts, :searchable, :boolean, default: true, if_not_exists: true
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
- class AddSearchableToAlchemyEssenceRichtexts < ActiveRecord::Migration[5.1]
1
+ class AddSearchableToAlchemyEssenceRichtexts < ActiveRecord::Migration[6.1]
2
2
  def change
3
- add_column :alchemy_essence_richtexts, :searchable, :boolean, default: true
3
+ add_column :alchemy_essence_richtexts, :searchable, :boolean, default: true, if_not_exists: true
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
- class AddSearchableToAlchemyEssencePictures < ActiveRecord::Migration[5.1]
1
+ class AddSearchableToAlchemyEssencePictures < ActiveRecord::Migration[6.1]
2
2
  def change
3
- add_column :alchemy_essence_pictures, :searchable, :boolean, default: true
3
+ add_column :alchemy_essence_pictures, :searchable, :boolean, default: true, if_not_exists: true
4
4
  end
5
5
  end
@@ -1,5 +1,9 @@
1
- class MoveSearchableToContents < ActiveRecord::Migration[5.0]
1
+ class MoveSearchableToContents < ActiveRecord::Migration[6.1]
2
2
  def change
3
+ if column_exists? :alchemy_contents, :searchable
4
+ return
5
+ end
6
+
3
7
  add_column :alchemy_contents, :searchable, :boolean, default: true
4
8
 
5
9
  {
@@ -1,5 +1,7 @@
1
1
  class AddPageIdColumnToPgSearchDocuments < ActiveRecord::Migration[6.0]
2
2
  def change
3
- add_reference :pg_search_documents, :page, index: true
3
+ unless column_exists? :pg_search_documents, :page
4
+ add_reference :pg_search_documents, :page, index: true
5
+ end
4
6
  end
5
7
  end
@@ -0,0 +1,9 @@
1
+ class AddSearchableContent < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_column :pg_search_documents, :searchable_content, :virtual,
4
+ type: :tsvector,
5
+ as: "to_tsvector('#{Alchemy::PgSearch.config.fetch(:dictionary, "simple")}', coalesce(content, ''))",
6
+ stored: true,
7
+ if_not_exists: true
8
+ end
9
+ end
@@ -2,6 +2,7 @@ module Alchemy
2
2
  module PgSearch
3
3
  module Config
4
4
  @@config = {
5
+ dictionary: 'simple',
5
6
  paginate_per: 10
6
7
  }
7
8
 
@@ -24,7 +24,11 @@ module Alchemy
24
24
  # @link https://github.com/Casecommons/pg_search#searching-using-different-search-features
25
25
  ::PgSearch.multisearch_options = {
26
26
  using: {
27
- tsearch: { prefix: true }
27
+ tsearch: {
28
+ prefix: true,
29
+ dictionary: Alchemy::PgSearch.config.fetch(:dictionary, "simple"),
30
+ tsvector_column: 'searchable_content'
31
+ }
28
32
  }
29
33
  }
30
34
  end
@@ -5,7 +5,7 @@ module Alchemy
5
5
  ##
6
6
  # index all supported Alchemy models
7
7
  def self.rebuild
8
- ([Alchemy::Page, Alchemy::Ingredient] + Alchemy::PgSearch.searchable_essence_classes).each do |model|
8
+ [Alchemy::Page, Alchemy::Ingredient].each do |model|
9
9
  ::PgSearch::Multisearch.rebuild(model)
10
10
  end
11
11
  end
@@ -19,20 +19,16 @@ module Alchemy
19
19
  end
20
20
 
21
21
  ##
22
- # index a single page and indexable essences
22
+ # index a single page and indexable ingredients
23
23
  #
24
24
  # @param page [Alchemy::Page]
25
25
  def self.index_page(page)
26
26
  remove_page page
27
27
 
28
28
  page.update_pg_search_document
29
- page.all_elements.includes(:ingredients, contents: :essence).find_each do |element|
30
- element.contents.each do |content|
31
- content.essence.update_pg_search_document if Alchemy::PgSearch.is_searchable?(content.essence_type)
32
- end
33
-
34
- element.ingredients.each do |ingredient|
35
- ingredient.update_pg_search_document if Alchemy::PgSearch.is_searchable?(ingredient.type)
29
+ page.all_elements.includes(:ingredients).find_each do |element|
30
+ element.ingredients.select { |i| Alchemy::PgSearch.is_searchable?(i.type) }.each do |ingredient|
31
+ ingredient.update_pg_search_document
36
32
  end
37
33
  end
38
34
  end
@@ -1,5 +1,5 @@
1
1
  module Alchemy
2
2
  module PgSearch
3
- VERSION = "4.2.0"
3
+ VERSION = "5.1.0"
4
4
  end
5
5
  end
@@ -9,18 +9,11 @@ module Alchemy
9
9
  extend Config
10
10
 
11
11
  ##
12
- # is essence or ingredient searchable?
13
- # @param essence_type [string]
12
+ # is ingredient searchable?
13
+ # @param ingredient_type [string]
14
14
  # @return [boolean]
15
- def self.is_searchable?(essence_type)
16
- SEARCHABLE_INGREDIENTS.include?(essence_type.gsub(/Alchemy::(Essence|Ingredients::)/, ""))
17
- end
18
-
19
- ##
20
- # generate an array of all supported essences classes
21
- # @return [array]
22
- def self.searchable_essence_classes
23
- SEARCHABLE_INGREDIENTS.map { |k| "Alchemy::Essence#{k.classify}".constantize }
15
+ def self.is_searchable?(ingredient_type)
16
+ SEARCHABLE_INGREDIENTS.include?(ingredient_type.gsub(/Alchemy::Ingredients::/, ""))
24
17
  end
25
18
 
26
19
  ##
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alchemy-pg_search
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.0
4
+ version: 5.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas von Deyen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-23 00:00:00.000000000 Z
11
+ date: 2023-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: alchemy_cms
@@ -16,20 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '6.1'
19
+ version: '7.0'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '7'
22
+ version: '8'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '6.1'
29
+ version: '7.0'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '7'
32
+ version: '8'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: pg_search
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -116,11 +116,7 @@ files:
116
116
  - Rakefile
117
117
  - alchemy-pg_search.gemspec
118
118
  - app/controller/alchemy/pg_search/controller_methods.rb
119
- - app/extensions/alchemy/pg_search/content_extension.rb
120
119
  - app/extensions/alchemy/pg_search/element_extension.rb
121
- - app/extensions/alchemy/pg_search/essence_picture_extension.rb
122
- - app/extensions/alchemy/pg_search/essence_richtext_extension.rb
123
- - app/extensions/alchemy/pg_search/essence_text_extension.rb
124
120
  - app/extensions/alchemy/pg_search/ingredient_extension.rb
125
121
  - app/extensions/alchemy/pg_search/page_extension.rb
126
122
  - app/extensions/alchemy/pg_search/pg_search_document_extension.rb
@@ -138,6 +134,7 @@ files:
138
134
  - db/migrate/20141211110126_add_searchable_to_alchemy_essence_pictures.rb
139
135
  - db/migrate/20210923081905_move_searchable_to_contents.rb
140
136
  - db/migrate/20220826125413_add_page_id_column_to_pg_search_documents.rb
137
+ - db/migrate/20231218165617_add_searchable_content.rb
141
138
  - lib/alchemy-pg_search.rb
142
139
  - lib/alchemy/pg_search/config.rb
143
140
  - lib/alchemy/pg_search/engine.rb
@@ -158,14 +155,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
158
155
  requirements:
159
156
  - - ">="
160
157
  - !ruby/object:Gem::Version
161
- version: '0'
158
+ version: 3.0.0
162
159
  required_rubygems_version: !ruby/object:Gem::Requirement
163
160
  requirements:
164
161
  - - ">="
165
162
  - !ruby/object:Gem::Version
166
163
  version: '0'
167
- requirements: []
168
- rubygems_version: 3.1.6
164
+ requirements:
165
+ - PostgreSQL >= 12.x
166
+ rubygems_version: 3.4.17
169
167
  signing_key:
170
168
  specification_version: 4
171
169
  summary: This gem provides PostgreSQL full text search to Alchemy
@@ -1,19 +0,0 @@
1
- module Alchemy::PgSearch::ContentExtension
2
- module ClassMethods
3
- def new(attributes)
4
- super.tap do |content|
5
- content.searchable = content.definition.key?(:searchable) ? content.definition[:searchable] : true
6
- end
7
- end
8
-
9
- Alchemy::Content.singleton_class.prepend self
10
- end
11
-
12
- module InstanceMethods
13
- def searchable?
14
- searchable && element.searchable?
15
- end
16
-
17
- Alchemy::Content.prepend self
18
- end
19
- end
@@ -1,19 +0,0 @@
1
- module Alchemy::PgSearch::EssencePictureExtension
2
-
3
- def self.prepended(base)
4
- base.include PgSearch::Model
5
- base.multisearchable(
6
- against: [
7
- :caption
8
- ],
9
- additional_attributes: -> (essence_picture) { { page_id: essence_picture.page.id } },
10
- if: :searchable?
11
- )
12
- end
13
-
14
- def searchable?
15
- caption.present? && !!content&.searchable?
16
- end
17
- end
18
-
19
- Alchemy::EssencePicture.prepend(Alchemy::PgSearch::EssencePictureExtension)
@@ -1,20 +0,0 @@
1
- module Alchemy::PgSearch::EssenceRichtextExtension
2
-
3
- def self.prepended(base)
4
- base.include PgSearch::Model
5
- base.multisearchable(
6
- against: [
7
- :stripped_body
8
- ],
9
- additional_attributes: -> (essence_richtext) { { page_id: essence_richtext.page.id } },
10
- if: :searchable?
11
- )
12
- end
13
-
14
- def searchable?
15
- stripped_body.present? && !!content&.searchable?
16
- end
17
- end
18
-
19
- Alchemy::EssenceRichtext.prepend(Alchemy::PgSearch::EssenceRichtextExtension)
20
-
@@ -1,19 +0,0 @@
1
- module Alchemy::PgSearch::EssenceTextExtension
2
- def self.prepended(base)
3
- base.include PgSearch::Model
4
- base.multisearchable(
5
- against: [
6
- :body
7
- ],
8
- additional_attributes: -> (essence_text) { { page_id: essence_text.page.id } },
9
- if: :searchable?
10
- )
11
- end
12
-
13
- def searchable?
14
- body.present? && !!content&.searchable?
15
- end
16
- end
17
-
18
- Alchemy::EssenceText.prepend(Alchemy::PgSearch::EssenceTextExtension)
19
-