From a82d59e0a2d03c17a11858f571506bdaee560775 Mon Sep 17 00:00:00 2001 From: Sascha Karnatz Date: Thu, 13 Jul 2023 17:17:52 +0200 Subject: [PATCH 1/6] Improve ingredient extension - Use the multisearch configuration on the supported ingredients - Fix the search for image caption (previously only the object string was stored) - improve readability of the ingredient extension spec - add public and upload path to gitignore - the specs are creating small images to test the picture ingredient --- .gitignore | 2 + .../alchemy/pg_search/ingredient_extension.rb | 19 +- spec/dummy/config/alchemy/elements.yml | 11 ++ spec/lib/search_spec.rb | 14 +- spec/models/ingredient_spec.rb | 177 +++++++++--------- 5 files changed, 127 insertions(+), 96 deletions(-) diff --git a/.gitignore b/.gitignore index 0e341b3..b1f7195 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ Gemfile.lock spec/dummy/log/*.log spec/dummy/db/*.sqlite3* spec/dummy/tmp/* +spec/dummy/public/* +spec/dummy/uploads/* .ruby-* node_modules yarn.lock diff --git a/app/extensions/alchemy/pg_search/ingredient_extension.rb b/app/extensions/alchemy/pg_search/ingredient_extension.rb index 8823fd0..83ee0cd 100644 --- a/app/extensions/alchemy/pg_search/ingredient_extension.rb +++ b/app/extensions/alchemy/pg_search/ingredient_extension.rb @@ -1,13 +1,18 @@ module Alchemy::PgSearch::IngredientExtension - def self.prepended(base) - base.include PgSearch::Model - base.multisearchable( + + def self.multisearch_config + { against: [ :value, ], additional_attributes: ->(ingredient) { { page_id: ingredient.element.page.id } }, - if: :searchable?, - ) + if: :searchable? + } + end + + def self.prepended(base) + base.include PgSearch::Model + base.multisearchable(multisearch_config) end def searchable? @@ -17,4 +22,8 @@ def searchable? end end +# add the PgSearch model to all ingredients Alchemy::Ingredient.prepend(Alchemy::PgSearch::IngredientExtension) + +# only enable the search for Text, Richtext, and Picture +Alchemy::Ingredients::Picture.multisearchable(Alchemy::PgSearch::IngredientExtension.multisearch_config.merge({against: [:caption]})) diff --git a/spec/dummy/config/alchemy/elements.yml b/spec/dummy/config/alchemy/elements.yml index 5583470..1cc2326 100644 --- a/spec/dummy/config/alchemy/elements.yml +++ b/spec/dummy/config/alchemy/elements.yml @@ -70,3 +70,14 @@ type: EssencePicture nestable_elements: - article + +- name: ingredient_test + ingredients: + - role: ingredient_text + type: Text + - role: ingredient_richtext + type: Richtext + - role: ingredient_picture + type: Picture + nestable_elements: + - article diff --git a/spec/lib/search_spec.rb b/spec/lib/search_spec.rb index fb87f8b..a0955a4 100644 --- a/spec/lib/search_spec.rb +++ b/spec/lib/search_spec.rb @@ -2,17 +2,21 @@ describe Alchemy::PgSearch::Search do let(:page_version) { create(:alchemy_page_version, :published) } - let(:element) { create(:alchemy_element, :with_contents, name: "essence_test", public: true, page_version: page_version) } + let(:essence_element) { create(:alchemy_element, :with_contents, name: "essence_test", public: true, page_version: page_version) } + let(:ingredient_element) { create(:alchemy_element, :with_ingredients, name: "ingredient_test", public: true, page_version: page_version) } + let(:prepared_essences) do { :essence_text => :body, :essence_richtext => :body, :essence_picture => :caption }.each do |essence_name, field| - essence = element.content_by_name(essence_name).essence + essence = essence_element.content_by_name(essence_name).essence essence[field] = "foo" essence.save end end let(:prepared_ingredients) do - Alchemy::PgSearch::SEARCHABLE_INGREDIENTS.each do |ingredient_type| - create(:"alchemy_ingredient_#{ingredient_type.downcase}", value: "foo", element: element) + { :ingredient_text => :value, :ingredient_richtext => :value, :ingredient_picture => :value }.each do |ingredient_name, field| + ingredient = ingredient_element.ingredient_by_role(ingredient_name) + ingredient[field] = "foo" + ingredient.save end end let(:first_page) { Alchemy::Page.first } @@ -121,7 +125,7 @@ end context 'nested elements' do - let(:nested_element) { create(:alchemy_element, :with_contents, name: "article", public: true, page_version: page_version, parent_element: element) } + let(:nested_element) { create(:alchemy_element, :with_contents, name: "article", public: true, page_version: page_version, parent_element: essence_element) } before do nested_element diff --git a/spec/models/ingredient_spec.rb b/spec/models/ingredient_spec.rb index 88807f6..bb07aee 100644 --- a/spec/models/ingredient_spec.rb +++ b/spec/models/ingredient_spec.rb @@ -1,112 +1,117 @@ require "spec_helper" -describe Alchemy::Ingredient do - let(:element) do - page_version = create(:alchemy_page_version, :published) - create(:alchemy_element, :with_contents, name: "ingredient_test", public: true, page_version: page_version) - end +RSpec.shared_examples_for "it is searchable" do + describe "searchable?" do + subject { ingredient.searchable? } + + context "element and ingredient are searchable" do + it { is_expected.to be(true) } + + context "but configured as not searchable" do + before do + expect(ingredient).to receive(:definition).at_least(:once) do + { + searchable: false, + } + end + end - Alchemy::PgSearch::SEARCHABLE_INGREDIENTS.each do |ingredient_type| - describe ingredient_type do - let(:ingredient) { create(:"alchemy_ingredient_#{ingredient_type.downcase}", value: "foo", element: element) } + it { is_expected.to be(false) } + end + end - describe "searchable?" do - subject { ingredient.searchable? } + context "ingredient has no content" do + it "should be not searchable" do + ingredient.value = nil + expect(ingredient.searchable?).to be(false) + end + end - context "element and ingredient are searchable" do - it { is_expected.to be(true) } + context "element is not public" do + it "should be not searchable" do + element.public = false + expect(ingredient.searchable?).to be(false) + end + end - context "but configured as not searchable" do - before do - expect(ingredient).to receive(:definition).at_least(:once) do - { - searchable: false, - } - end - end + context "ingredient has no related content" do + let(:ingredient) { create(:alchemy_ingredient_text) } - it { is_expected.to be(false) } - end - end + it "should be not searchable" do + expect(ingredient.searchable?).to be(false) + end + end + end +end - context "ingredient has no content" do - it "should be not searchable" do - ingredient.value = nil - expect(ingredient.searchable?).to be(false) - end - end +RSpec.shared_examples_for "it is in search index" do + describe "search index" do + let(:document) { PgSearch::Document.first } - context "element is not public" do - it "should be not searchable" do - element.public = false - expect(ingredient.searchable?).to be(false) - end - end + subject do + ingredient + ::PgSearch::Multisearch.rebuild described_class + end + + it "should have one entry" do + subject + expect(PgSearch::Document.where(searchable_type: "Alchemy::Ingredient").count).to eq(1) + end - context "ingredient has no related content" do - let(:ingredient) { create(:alchemy_ingredient_text) } + it "should have the content" do + subject + expect(PgSearch::Document.first.content).to eq(content) + end - it "should be not searchable" do - expect(ingredient.searchable?).to be(false) - end + context "configured as not searchable" do + before do + expect_any_instance_of(ingredient.class).to receive(:definition).at_least(:once) do + { + searchable: false, + } end end - context "index" do - let(:document) { PgSearch::Document.first } + it "should have no index entry" do + subject + expect(PgSearch::Document.where(searchable_type: "Alchemy::Ingredient").count).to eq(0) + end + end - subject do - ingredient - ::PgSearch::Multisearch.rebuild Alchemy::Ingredient - end + it "should be the current ingredient" do + subject + expect(document.searchable).to eq(ingredient) + end + end +end - it "should have one entry" do - subject - expect(PgSearch::Document.where(searchable_type: "Alchemy::Ingredient").count).to eq(1) - end +describe Alchemy::Ingredient do + let(:element) do + page_version = create(:alchemy_page_version, :published) + create(:alchemy_element, :with_contents, name: "ingredient_test", public: true, page_version: page_version) + end - context "configured as not searchable" do - before do - expect_any_instance_of(ingredient.class).to receive(:definition).at_least(:once) do - { - searchable: false, - } - end - end + let(:content) { "foo bar"} - it "should have no index entry" do - subject - expect(PgSearch::Document.where(searchable_type: "Alchemy::Ingredient").count).to eq(0) - end - end + describe Alchemy::Ingredients::Text do + let(:ingredient) { create(:alchemy_ingredient_text, value: content, element: element) } - it "should be the current ingredient" do - subject - expect(document.searchable).to eq(ingredient) - end - end - end + it_behaves_like "it is searchable" + it_behaves_like "it is in search index" end - context "not supported ingredient type" do - let(:ingredient) { create(:"alchemy_ingredient_boolean", value: true, element: element) } + describe Alchemy::Ingredients::Richtext do + let(:ingredient) { create(:alchemy_ingredient_richtext, value: content, element: element) } + let(:ingredient_class) { Alchemy::Ingredients::Text } - context "searchable?" do - it "should be not searchable" do - expect(ingredient.searchable?).to be(false) - end - end + it_behaves_like "it is searchable" + it_behaves_like "it is in search index" + end - context "index" do - let(:document) { PgSearch::Document.first } - before do - ingredient - ::PgSearch::Multisearch.rebuild Alchemy::Ingredient - end + describe Alchemy::Ingredients::Picture do + let(:ingredient) { create(:alchemy_ingredient_picture, value: create(:alchemy_picture), caption: content, element: element) } - it "should have no entries" do - expect(PgSearch::Document.all.length).to eq(0) - end - end + it_behaves_like "it is searchable" + it_behaves_like "it is in search index" end end From 292c48f1489bf83fee391d0b13892987b178bd12 Mon Sep 17 00:00:00 2001 From: Sascha Karnatz Date: Thu, 13 Jul 2023 17:24:05 +0200 Subject: [PATCH 2/6] Migrate from contents to ingredients in element.yml Update the full text search spec to use ingredients instead of essences. --- spec/dummy/config/alchemy/elements.yml | 68 +++++++++---------- spec/features/fulltext_search_feature_spec.rb | 53 +++++++-------- spec/lib/search_spec.rb | 7 +- 3 files changed, 62 insertions(+), 66 deletions(-) diff --git a/spec/dummy/config/alchemy/elements.yml b/spec/dummy/config/alchemy/elements.yml index 1cc2326..b07c7ff 100644 --- a/spec/dummy/config/alchemy/elements.yml +++ b/spec/dummy/config/alchemy/elements.yml @@ -1,63 +1,63 @@ - name: article - contents: - - name: headline - type: EssenceText + ingredients: + - role: headline + type: Text default: "This is a headline everybody should be able to search for." - - name: text - type: EssenceRichtext + - role: text + type: Richtext default: "This is a text block everybody should be able to search for." - - name: image - type: EssencePicture + - role: image + type: Picture - name: secrets - contents: - - name: passwords - type: EssenceText + ingredients: + - role: passwords + type: Text searchable: false default: "This is my secret password." - - name: confidential - type: EssenceRichtext + - role: confidential + type: Richtext searchable: false default: "This is some confidential text." - - name: image - type: EssencePicture + - role: image + type: Picture searchable: false - name: mixed - contents: - - name: title - type: EssenceText + ingredients: + - role: title + type: Text default: "This is my public title." - - name: password - type: EssenceText + - role: password + type: Text default: "This is my secret password." searchable: false - - name: public - type: EssenceRichtext + - role: public + type: Richtext default: "This is some public text." - - name: confidential - type: EssenceRichtext + - role: confidential + type: Richtext searchable: false default: "This is some confidential text." - - name: image - type: EssencePicture - - name: secret_image - type: EssencePicture + - role: image + type: Picture + - role: secret_image + type: Picture searchable: false - name: searchresults unique: true - name: content_test - contents: - - name: without_searchable - type: EssenceText + ingredients: + - role: without_searchable + type: Text default: "This is my public title." - - name: with_searchable_enabled - type: EssenceText + - role: with_searchable_enabled + type: Text searchable: true - - name: with_searchable_disabled - type: EssenceText + - role: with_searchable_disabled + type: Text searchable: false - name: essence_test diff --git a/spec/features/fulltext_search_feature_spec.rb b/spec/features/fulltext_search_feature_spec.rb index 2bee41b..7daf51e 100644 --- a/spec/features/fulltext_search_feature_spec.rb +++ b/spec/features/fulltext_search_feature_spec.rb @@ -12,7 +12,14 @@ context "displaying search results" do let!(:public_page) { create(:alchemy_page, :public, name: "Page 1") } - let!(:element) { create(:alchemy_element, :with_contents, page_version: public_page.public_version) } + let!(:element) { create(:alchemy_element, :with_ingredients, name: "article", page_version: public_page.public_version) } + let(:image_caption) { "This is a caption everybody should be able to search for." } + let!(:image) do + image = element.ingredient_by_role(:image) + image.picture = create(:alchemy_picture) + image.caption = image_caption + image.save + end it "displays search results from text essences" do visit("/suche?query=search") @@ -28,25 +35,21 @@ end end - it "displays search results from picture essences" do - element.contents.essence_pictures.first.essence.update!(caption: "This is a caption everybody should be able to search for.") + it "displays search results from picture ingredient" do visit("/suche?query=caption") within(".search_results") do expect(page).to have_content("This is a caption everybody should be able to search for.") end end - context "with unsearchable contents" do - let!(:secret_element) do - create(:alchemy_element, :with_contents, page_version: public_page.public_version, name: "secrets") - end - - before do - secret_element.contents.essence_pictures.first.essence.update!(caption: "This is a secret caption.") + context "with unsearchable ingredients" do + let!(:element) do + create(:alchemy_element, :with_ingredients, page_version: public_page.public_version, name: "secrets") end + let(:image_caption) { "This is a secret caption." } it "does not display results from unsearchable contents" do - visit("/suche?query=This") + visit("/suche?query=secret") expect(page).to_not have_content("This is my secret password") expect(page).to_not have_content("This is some confidential text") expect(page).to_not have_content("This is a secret caption") @@ -100,7 +103,7 @@ let(:english_language) { create(:alchemy_language, :english) } let(:english_language_root) { create(:alchemy_page, :language_root, language: english_language, name: "Home") } let(:english_page) { create(:alchemy_page, :public, parent_id: english_language_root.id, language: english_language) } - let!(:english_element) { create(:alchemy_element, :with_contents, page: english_page, name: "article") } + let!(:english_element) { create(:alchemy_element, :with_ingredients, page: english_page, name: "article") } before do element @@ -108,7 +111,7 @@ end it "does not display search results from other languages" do - english_element.content_by_name("headline").essence.update!(body: "Joes Hardware") + english_element.ingredient_by_role("headline").update!(value: "Joes Hardware") visit("/de/suche?query=Hardware") expect(page).to have_css("h2.no_search_results") expect(page).to_not have_css(".search_result_list") @@ -119,16 +122,15 @@ let!(:nested_element) do create( :alchemy_element, - :with_contents, + :with_ingredients, + name: "article", page_version: public_page.public_version, parent_element: element, ) end before do - nested_element.content_by_name("headline").essence.update!({ - body: "Content from nested element", - }) + nested_element.ingredient_by_role("headline").update!({ value: "Content from nested element" }) end it "displays search results from nested elements" do @@ -143,12 +145,9 @@ let!(:public_page) { create(:alchemy_page, :public, name: "Page 1") } let!(:element) do - create(:alchemy_element, :with_contents, public: false, page_version: public_page.public_version) - end - - before do - element.contents.essence_pictures.first.essence.update!(caption: "This is a secret caption.") + create(:alchemy_element, :with_ingredients, name: "article", public: false, page_version: public_page.public_version) end + let(:image_caption) { "This is a secret caption." } it "does not displays search results" do visit("/suche?query=caption") @@ -162,12 +161,9 @@ let!(:public_page) { create(:alchemy_page, :public, name: "Page 1") } let!(:element) do - create(:alchemy_element, :with_contents, public: true, page_version: public_page.public_version) - end - - before do - element.contents.essence_pictures.first.essence.update!(caption: "This is a secret caption.") + create(:alchemy_element, :with_ingredients, name: "article", public: true, page_version: public_page.public_version) end + let(:image_caption) { "This is a secret caption." } it "displays search results" do visit("/suche?query=caption") @@ -183,7 +179,8 @@ 12.times do create( :alchemy_element, - :with_contents, + :with_ingredients, + name: "article", page_version: create(:alchemy_page, :public).public_version, ) end diff --git a/spec/lib/search_spec.rb b/spec/lib/search_spec.rb index a0955a4..ab46697 100644 --- a/spec/lib/search_spec.rb +++ b/spec/lib/search_spec.rb @@ -125,15 +125,14 @@ end context 'nested elements' do - let(:nested_element) { create(:alchemy_element, :with_contents, name: "article", public: true, page_version: page_version, parent_element: essence_element) } + let!(:nested_element) { create(:alchemy_element, :with_ingredients, name: "article", public: true, page_version: page_version, parent_element: ingredient_element) } before do - nested_element Alchemy::PgSearch::Search.index_page second_page end - it 'should have 6 documents' do - # 1 Page + 3 previous essences + 3 previous ingredients + 2 new article essences + it 'should have 9 documents' do + # 1 Page + 3 previous essences + 3 previous ingredients + 2 new article ingredients # the picture essence is empty and not in the search index expect(PgSearch::Document.count).to be(9) end From 827971b2bbbd6df4b49bcd471ddbbf448488d9ba Mon Sep 17 00:00:00 2001 From: Sascha Karnatz Date: Mon, 24 Jul 2023 14:39:51 +0200 Subject: [PATCH 3/6] Update the dummy app to Rails 7.0 update dummy app to the latest Rails version. ActiveRecord changed the implementation of first, which broke a test for the search method. I fixed it by loading the whole result. This is not a very good solution it has to be optimized in the future. --- Gemfile | 2 +- spec/dummy/config.ru | 4 ++- spec/dummy/config/application.rb | 2 +- spec/dummy/config/environments/development.rb | 29 ++++++++++++------- spec/dummy/config/environments/production.rb | 18 ++++++++---- spec/dummy/config/environments/test.rb | 13 ++++++++- .../initializers/backtrace_silencers.rb | 7 +++-- .../config/initializers/permissions_policy.rb | 11 +++++++ spec/dummy/config/puma.rb | 7 ++++- spec/lib/search_spec.rb | 2 +- 10 files changed, 70 insertions(+), 25 deletions(-) create mode 100644 spec/dummy/config/initializers/permissions_policy.rb diff --git a/Gemfile b/Gemfile index e84736d..54ed4b0 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source "https://rubygems.org" gemspec -gem "rails", "~> 6.0.0" +gem "rails", "~> 7.0.0" ENV.fetch("ALCHEMY_BRANCH", "6.1-stable").tap do |branch| gem "alchemy_cms", github: "AlchemyCMS/alchemy_cms", branch: branch end diff --git a/spec/dummy/config.ru b/spec/dummy/config.ru index bd83b25..4a3c09a 100644 --- a/spec/dummy/config.ru +++ b/spec/dummy/config.ru @@ -1,4 +1,6 @@ # This file is used by Rack-based servers to start the application. -require ::File.expand_path('../config/environment', __FILE__) +require_relative "config/environment" + run Rails.application +Rails.application.load_server diff --git a/spec/dummy/config/application.rb b/spec/dummy/config/application.rb index 0900387..b222a3b 100644 --- a/spec/dummy/config/application.rb +++ b/spec/dummy/config/application.rb @@ -23,7 +23,7 @@ module Dummy class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 5.1 + config.load_defaults 7.0 # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers diff --git a/spec/dummy/config/environments/development.rb b/spec/dummy/config/environments/development.rb index efa151f..5eed9fc 100644 --- a/spec/dummy/config/environments/development.rb +++ b/spec/dummy/config/environments/development.rb @@ -1,8 +1,10 @@ +require "active_support/core_ext/integer/time" + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # In the development environment your application's code is reloaded on - # every request. This slows down response time but is perfect for development + # In the development environment your application's code is reloaded any time + # it changes. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. config.cache_classes = false @@ -12,6 +14,8 @@ # Show full error reports. config.consider_all_requests_local = true + # Enable server timing + config.server_timing = true # Enable/disable caching. By default caching is disabled. # Run rails dev:cache to toggle caching. if Rails.root.join('tmp', 'caching-dev.txt').exist? @@ -36,24 +40,27 @@ # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + # Raise an error on page load if there are pending migrations. config.active_record.migration_error = :page_load # Highlight code that triggered database queries in logs. config.active_record.verbose_query_logs = true - # Debug mode disables concatenation and preprocessing of assets. - # This option may cause significant delays in view rendering with a large - # number of complex assets. - config.assets.debug = true - # Suppress logger output for asset requests. config.assets.quiet = true # Raises error for missing translations. - # config.action_view.raise_on_missing_translations = true + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true - # Use an evented file watcher to asynchronously detect changes in source code, - # routes, locales, etc. This feature depends on the listen gem. - config.file_watcher = ActiveSupport::EventedFileUpdateChecker + # Uncomment if you wish to allow Action Cable access from any origin. + # config.action_cable.disable_request_forgery_protection = true end diff --git a/spec/dummy/config/environments/production.rb b/spec/dummy/config/environments/production.rb index b6e408c..9a0f5e0 100644 --- a/spec/dummy/config/environments/production.rb +++ b/spec/dummy/config/environments/production.rb @@ -1,3 +1,5 @@ +require "active_support/core_ext/integer/time" + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -29,7 +31,7 @@ config.assets.compile = false # Enable serving of images, stylesheets, and JavaScripts from an asset server. - # config.action_controller.asset_host = 'http://assets.example.com' + # config.asset_host = 'http://assets.example.com' # Specifies the header that your server uses for sending files. # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache @@ -38,9 +40,9 @@ # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true - # Use the lowest log level to ensure availability of diagnostic information - # when problems arise. - config.log_level = :debug + # Include generic and useful information about system operation, but avoid logging too much + # information to avoid inadvertent exposure of personally identifiable information (PII). + config.log_level = :info # Prepend all log lines with the following tags. config.log_tags = [ :request_id ] @@ -65,11 +67,17 @@ # Send deprecation notices to registered listeners. config.active_support.deprecation = :notify + # Log disallowed deprecations. + config.active_support.disallowed_deprecation = :log + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + # Use default logging formatter so that PID and timestamp are not suppressed. config.log_formatter = ::Logger::Formatter.new # Use a different logger for distributed setups. - # require 'syslog/logger' + # require "syslog/logger" # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') if ENV["RAILS_LOG_TO_STDOUT"].present? diff --git a/spec/dummy/config/environments/test.rb b/spec/dummy/config/environments/test.rb index 2f62f93..d66c042 100644 --- a/spec/dummy/config/environments/test.rb +++ b/spec/dummy/config/environments/test.rb @@ -1,3 +1,5 @@ +require "active_support/core_ext/integer/time" + # The test environment is used exclusively to run your application's # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped @@ -40,6 +42,15 @@ # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + # Raises error for missing translations. - # config.action_view.raise_on_missing_translations = true + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true end diff --git a/spec/dummy/config/initializers/backtrace_silencers.rb b/spec/dummy/config/initializers/backtrace_silencers.rb index 59385cd..33699c3 100644 --- a/spec/dummy/config/initializers/backtrace_silencers.rb +++ b/spec/dummy/config/initializers/backtrace_silencers.rb @@ -1,7 +1,8 @@ # Be sure to restart your server when you modify this file. # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. -# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } +# Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) } -# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. -# Rails.backtrace_cleaner.remove_silencers! +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code +# by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'". +Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"] diff --git a/spec/dummy/config/initializers/permissions_policy.rb b/spec/dummy/config/initializers/permissions_policy.rb new file mode 100644 index 0000000..00f64d7 --- /dev/null +++ b/spec/dummy/config/initializers/permissions_policy.rb @@ -0,0 +1,11 @@ +# Define an application-wide HTTP permissions policy. For further +# information see https://developers.google.com/web/updates/2018/06/feature-policy +# +# Rails.application.config.permissions_policy do |f| +# f.camera :none +# f.gyroscope :none +# f.microphone :none +# f.usb :none +# f.fullscreen :self +# f.payment :self, "https://secure.example.com" +# end diff --git a/spec/dummy/config/puma.rb b/spec/dummy/config/puma.rb index 5ed4437..d9b3e83 100644 --- a/spec/dummy/config/puma.rb +++ b/spec/dummy/config/puma.rb @@ -8,9 +8,14 @@ min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } threads min_threads_count, max_threads_count +# Specifies the `worker_timeout` threshold that Puma will use to wait before +# terminating a worker in development environments. +# +worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" + # Specifies the `port` that Puma will listen on to receive requests; default is 3000. # -port ENV.fetch("PORT") { 3000 } +port ENV.fetch("PORT") { 3000 } # Specifies the `environment` that Puma will run in. # diff --git a/spec/lib/search_spec.rb b/spec/lib/search_spec.rb index ab46697..38c69e1 100644 --- a/spec/lib/search_spec.rb +++ b/spec/lib/search_spec.rb @@ -198,7 +198,7 @@ end it 'should find only the second page' do - expect(result.first.page).to eq(second_page) + expect(result.take.page).to eq(second_page) end end end From 14beb60ade307978b25356a0c2e2c566adb5a826 Mon Sep 17 00:00:00 2001 From: Sascha Karnatz Date: Mon, 24 Jul 2023 15:16:11 +0200 Subject: [PATCH 4/6] Remove essences support Remove all extensions for essences and contents. This will prepare the update to Alchemy 7.0, which does not support essences anymore. --- README.md | 12 ++-- .../alchemy/pg_search/content_extension.rb | 19 ------- .../pg_search/essence_picture_extension.rb | 19 ------- .../pg_search/essence_richtext_extension.rb | 20 ------- .../pg_search/essence_text_extension.rb | 19 ------- lib/alchemy-pg_search.rb | 15 ++--- lib/alchemy/pg_search/search.rb | 14 ++--- spec/dummy/config/alchemy/elements.yml | 11 ---- spec/features/fulltext_search_feature_spec.rb | 2 +- spec/lib/search_spec.rb | 37 ++++-------- spec/models/content_spec.rb | 57 ------------------- spec/models/essence_picture_spec.rb | 43 -------------- spec/models/essence_richtext_spec.rb | 47 --------------- spec/models/essence_text_spec.rb | 43 -------------- spec/models/ingredient_spec.rb | 5 +- 15 files changed, 28 insertions(+), 335 deletions(-) delete mode 100644 app/extensions/alchemy/pg_search/content_extension.rb delete mode 100644 app/extensions/alchemy/pg_search/essence_picture_extension.rb delete mode 100644 app/extensions/alchemy/pg_search/essence_richtext_extension.rb delete mode 100644 app/extensions/alchemy/pg_search/essence_text_extension.rb delete mode 100644 spec/models/content_spec.rb delete mode 100644 spec/models/essence_picture_spec.rb delete mode 100644 spec/models/essence_richtext_spec.rb delete mode 100644 spec/models/essence_text_spec.rb diff --git a/README.md b/README.md index 221d80e..e7839a2 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ $ bin/rails g alchemy:pg_search:install ## Usage -Every `EssenceText`, `EssenceRichtext` and `EssencePicture` will be indexed unless you tell Alchemy to not index a specific content. +Every `Ingredient` will be indexed unless you tell Alchemy to not index a specific content. ### Disable Indexing @@ -51,7 +51,7 @@ Pass `searchable: false` to your element definitions and Alchemy will not index - name: secret_sauce searchable: false ingredients: - - name: sauce + - role: sauce type: Text default: 'This is my secret sauce.' ``` @@ -63,9 +63,9 @@ Pass `searchable: false` to your content definitions and Alchemy will not index ```yaml # elements.yml - name: secrets - contents: - - name: passwords - type: EssenceText + ingredients: + - role: passwords + type: Text searchable: false default: 'This is my secret password.' ``` @@ -76,7 +76,7 @@ The same works for `ingredients` as well # elements.yml - name: secrets ingredients: - - name: passwords + - role: passwords type: Text searchable: false default: 'This is my secret password.' diff --git a/app/extensions/alchemy/pg_search/content_extension.rb b/app/extensions/alchemy/pg_search/content_extension.rb deleted file mode 100644 index 9a6b821..0000000 --- a/app/extensions/alchemy/pg_search/content_extension.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Alchemy::PgSearch::ContentExtension - module ClassMethods - def new(attributes) - super.tap do |content| - content.searchable = content.definition.key?(:searchable) ? content.definition[:searchable] : true - end - end - - Alchemy::Content.singleton_class.prepend self - end - - module InstanceMethods - def searchable? - searchable && element.searchable? - end - - Alchemy::Content.prepend self - end -end diff --git a/app/extensions/alchemy/pg_search/essence_picture_extension.rb b/app/extensions/alchemy/pg_search/essence_picture_extension.rb deleted file mode 100644 index 747f2e7..0000000 --- a/app/extensions/alchemy/pg_search/essence_picture_extension.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Alchemy::PgSearch::EssencePictureExtension - - def self.prepended(base) - base.include PgSearch::Model - base.multisearchable( - against: [ - :caption - ], - additional_attributes: -> (essence_picture) { { page_id: essence_picture.page.id } }, - if: :searchable? - ) - end - - def searchable? - caption.present? && !!content&.searchable? - end -end - -Alchemy::EssencePicture.prepend(Alchemy::PgSearch::EssencePictureExtension) diff --git a/app/extensions/alchemy/pg_search/essence_richtext_extension.rb b/app/extensions/alchemy/pg_search/essence_richtext_extension.rb deleted file mode 100644 index ef19102..0000000 --- a/app/extensions/alchemy/pg_search/essence_richtext_extension.rb +++ /dev/null @@ -1,20 +0,0 @@ -module Alchemy::PgSearch::EssenceRichtextExtension - - def self.prepended(base) - base.include PgSearch::Model - base.multisearchable( - against: [ - :stripped_body - ], - additional_attributes: -> (essence_richtext) { { page_id: essence_richtext.page.id } }, - if: :searchable? - ) - end - - def searchable? - stripped_body.present? && !!content&.searchable? - end -end - -Alchemy::EssenceRichtext.prepend(Alchemy::PgSearch::EssenceRichtextExtension) - diff --git a/app/extensions/alchemy/pg_search/essence_text_extension.rb b/app/extensions/alchemy/pg_search/essence_text_extension.rb deleted file mode 100644 index 8789977..0000000 --- a/app/extensions/alchemy/pg_search/essence_text_extension.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Alchemy::PgSearch::EssenceTextExtension - def self.prepended(base) - base.include PgSearch::Model - base.multisearchable( - against: [ - :body - ], - additional_attributes: -> (essence_text) { { page_id: essence_text.page.id } }, - if: :searchable? - ) - end - - def searchable? - body.present? && !!content&.searchable? - end -end - -Alchemy::EssenceText.prepend(Alchemy::PgSearch::EssenceTextExtension) - diff --git a/lib/alchemy-pg_search.rb b/lib/alchemy-pg_search.rb index de82e6c..40ffac9 100644 --- a/lib/alchemy-pg_search.rb +++ b/lib/alchemy-pg_search.rb @@ -9,18 +9,11 @@ module PgSearch extend Config ## - # is essence or ingredient searchable? - # @param essence_type [string] + # is ingredient searchable? + # @param ingredient_type [string] # @return [boolean] - def self.is_searchable?(essence_type) - SEARCHABLE_INGREDIENTS.include?(essence_type.gsub(/Alchemy::(Essence|Ingredients::)/, "")) - end - - ## - # generate an array of all supported essences classes - # @return [array] - def self.searchable_essence_classes - SEARCHABLE_INGREDIENTS.map { |k| "Alchemy::Essence#{k.classify}".constantize } + def self.is_searchable?(ingredient_type) + SEARCHABLE_INGREDIENTS.include?(ingredient_type.gsub(/Alchemy::Ingredients::/, "")) end ## diff --git a/lib/alchemy/pg_search/search.rb b/lib/alchemy/pg_search/search.rb index 560f786..97b401d 100644 --- a/lib/alchemy/pg_search/search.rb +++ b/lib/alchemy/pg_search/search.rb @@ -5,7 +5,7 @@ module Search ## # index all supported Alchemy models def self.rebuild - ([Alchemy::Page, Alchemy::Ingredient] + Alchemy::PgSearch.searchable_essence_classes).each do |model| + [Alchemy::Page, Alchemy::Ingredient].each do |model| ::PgSearch::Multisearch.rebuild(model) end end @@ -19,20 +19,16 @@ def self.remove_page(page) end ## - # index a single page and indexable essences + # index a single page and indexable ingredients # # @param page [Alchemy::Page] def self.index_page(page) remove_page page page.update_pg_search_document - page.all_elements.includes(:ingredients, contents: :essence).find_each do |element| - element.contents.each do |content| - content.essence.update_pg_search_document if Alchemy::PgSearch.is_searchable?(content.essence_type) - end - - element.ingredients.each do |ingredient| - ingredient.update_pg_search_document if Alchemy::PgSearch.is_searchable?(ingredient.type) + page.all_elements.includes(:ingredients).find_each do |element| + element.ingredients.select { |i| Alchemy::PgSearch.is_searchable?(i.type) }.each do |ingredient| + ingredient.update_pg_search_document end end end diff --git a/spec/dummy/config/alchemy/elements.yml b/spec/dummy/config/alchemy/elements.yml index b07c7ff..90581b1 100644 --- a/spec/dummy/config/alchemy/elements.yml +++ b/spec/dummy/config/alchemy/elements.yml @@ -60,17 +60,6 @@ type: Text searchable: false -- name: essence_test - contents: - - name: essence_text - type: EssenceText - - name: essence_richtext - type: EssenceRichtext - - name: essence_picture - type: EssencePicture - nestable_elements: - - article - - name: ingredient_test ingredients: - role: ingredient_text diff --git a/spec/features/fulltext_search_feature_spec.rb b/spec/features/fulltext_search_feature_spec.rb index 7daf51e..c7f6df5 100644 --- a/spec/features/fulltext_search_feature_spec.rb +++ b/spec/features/fulltext_search_feature_spec.rb @@ -21,7 +21,7 @@ image.save end - it "displays search results from text essences" do + it "displays search results from text ingredients" do visit("/suche?query=search") within(".search_results") do expect(page).to have_content("This is a headline everybody should be able to search for.") diff --git a/spec/lib/search_spec.rb b/spec/lib/search_spec.rb index 38c69e1..ab7c38e 100644 --- a/spec/lib/search_spec.rb +++ b/spec/lib/search_spec.rb @@ -2,16 +2,8 @@ describe Alchemy::PgSearch::Search do let(:page_version) { create(:alchemy_page_version, :published) } - let(:essence_element) { create(:alchemy_element, :with_contents, name: "essence_test", public: true, page_version: page_version) } let(:ingredient_element) { create(:alchemy_element, :with_ingredients, name: "ingredient_test", public: true, page_version: page_version) } - let(:prepared_essences) do - { :essence_text => :body, :essence_richtext => :body, :essence_picture => :caption }.each do |essence_name, field| - essence = essence_element.content_by_name(essence_name).essence - essence[field] = "foo" - essence.save - end - end let(:prepared_ingredients) do { :ingredient_text => :value, :ingredient_richtext => :value, :ingredient_picture => :value }.each do |ingredient_name, field| ingredient = ingredient_element.ingredient_by_role(ingredient_name) @@ -29,20 +21,14 @@ context 'after rebuild' do before do - prepared_essences prepared_ingredients Alchemy::PgSearch::Search.rebuild end - it 'should have entries (2 Pages + 3 Essences + 3 Ingredients)' do - expect(PgSearch::Document.count).to eq(8) + it 'should have entries (2 Pages + 3 Ingredients)' do + expect(PgSearch::Document.count).to eq(5) end - ["Alchemy::EssenceText", "Alchemy::EssenceRichtext", "Alchemy::EssencePicture"].each do |model| - it "should have a #{model}" do - expect(PgSearch::Document.where(searchable_type: model).count).to eq(1) - end - end it "should have three ingredients" do expect(PgSearch::Document.where(searchable_type: "Alchemy::Ingredient").count).to eq(3) @@ -52,7 +38,6 @@ context 'remove_page' do before do - prepared_essences prepared_ingredients Alchemy::PgSearch::Search.rebuild end @@ -60,8 +45,8 @@ context 'remove first page' do before { Alchemy::PgSearch::Search.remove_page first_page } - it 'should have only one page and relative essences/ingredients (1 Page + 3 Essences + 3 Ingredients)' do - expect(PgSearch::Document.count).to eq(7) + it 'should have only one page and relative ingredients (1 Page + 3 Ingredients)' do + expect(PgSearch::Document.count).to eq(4) end it 'should have one page entry' do @@ -85,7 +70,6 @@ context 'index_page' do before do - prepared_essences prepared_ingredients PgSearch::Document.destroy_all # clean the whole index end @@ -113,8 +97,8 @@ Alchemy::PgSearch::Search.index_page second_page end - it 'should have four entries (1 Page + 3 Essences + 3 Ingredients)' do - expect(PgSearch::Document.count).to be(7) + it 'should have four entries (1 Page + 3 Ingredients)' do + expect(PgSearch::Document.count).to be(4) end it 'should be all relate to the same page ' do @@ -131,10 +115,9 @@ Alchemy::PgSearch::Search.index_page second_page end - it 'should have 9 documents' do - # 1 Page + 3 previous essences + 3 previous ingredients + 2 new article ingredients - # the picture essence is empty and not in the search index - expect(PgSearch::Document.count).to be(9) + it 'should have 6 documents' do + # 1 Page + 3 previous ingredients + 2 new article ingredients + expect(PgSearch::Document.count).to be(6) end it 'should be all relate to the same page ' do @@ -172,7 +155,7 @@ before do create(:alchemy_page, :restricted, :public, name: "foo") - prepared_essences + prepared_ingredients Alchemy::PgSearch::Search.rebuild end diff --git a/spec/models/content_spec.rb b/spec/models/content_spec.rb deleted file mode 100644 index b6bedfc..0000000 --- a/spec/models/content_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -require "spec_helper" - -RSpec.describe Alchemy::Content do - let(:element_public) { true } - let(:element) do - page_version = create(:alchemy_page_version, :published) - create(:alchemy_element, :with_contents, name: "content_test", public: element_public, page_version: page_version) - end - let(:content) { element.content_by_name(content_name) } - let(:content_name) { :without_searchable } - - context "searchable?" do - context "content and element are searchable" do - it "should be searchable" do - expect(content.searchable?).to be(true) - end - end - - context "content not marked as searchable" do - let(:content_name) { :with_searchable_disabled } - it "should not be searchable" do - expect(content.searchable?).to be(false) - end - end - - context "related element not searchable" do - let(:element_public) { false } - it "should not be searchable" do - expect(content.searchable?).to be(false) - end - end - end - - context "Without searchable" do - let(:content_name) { :without_searchable } - - it "should be marked as searchable" do - expect(content.searchable).to be(true) - end - end - - context "With searchable enabled" do - let(:content_name) { :with_searchable_enabled } - - it "should be marked as searchable" do - expect(content.searchable).to be(true) - end - end - - context "With searchable disabled" do - let(:content_name) { :with_searchable_disabled } - - it "should be not marked as searchable" do - expect(content.searchable).to be(false) - end - end -end diff --git a/spec/models/essence_picture_spec.rb b/spec/models/essence_picture_spec.rb deleted file mode 100644 index a8871b3..0000000 --- a/spec/models/essence_picture_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -require "spec_helper" - -describe Alchemy::EssencePicture do - let(:element) do - page_version = create(:alchemy_page_version, :published) - create(:alchemy_element, :with_contents, name: "essence_test", public: true, page_version: page_version) - end - let(:essence_picture) do - essence = element.content_by_name("essence_picture").essence - essence.caption = "foo" - essence - end - - context "searchable?" do - context "content and essence_picture are searchable" do - it "should be searchable" do - expect(essence_picture.searchable?).to be(true) - end - end - - context "essence_picture has no content" do - it "should be not searchable" do - essence_picture.caption = nil - expect(essence_picture.searchable?).to be(false) - end - end - - context "element is not public" do - it "should be not searchable" do - element.public = false - expect(essence_picture.searchable?).to be(false) - end - end - - context "essence_picture has no related content" do - let(:essence_picture) { create(:alchemy_essence_picture) } - - it "should be not searchable" do - expect(essence_picture.searchable?).to be(false) - end - end - end -end diff --git a/spec/models/essence_richtext_spec.rb b/spec/models/essence_richtext_spec.rb deleted file mode 100644 index 0b45506..0000000 --- a/spec/models/essence_richtext_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -require "spec_helper" - -describe Alchemy::EssenceRichtext do - let(:element) do - page_version = create(:alchemy_page_version, :published) - create(:alchemy_element, :with_contents, name: "essence_test", public: true, page_version: page_version) - end - let(:essence_richtext) do - essence = element.content_by_name("essence_richtext").essence - essence.stripped_body = "foo" - essence - end - - context "searchable?" do - context "content and essence_richtext are searchable" do - it "should be searchable" do - expect(essence_richtext.searchable?).to be(true) - end - end - - context "essence_richtext has no content" do - it "should be not searchable" do - essence_richtext.stripped_body = nil - expect(essence_richtext.searchable?).to be(false) - end - end - - context "element is not public" do - it "should be not searchable" do - element.public = false - expect(essence_richtext.searchable?).to be(false) - end - end - - context "essence_richtext has no related content" do - let(:essence_richtext) do - Alchemy::EssenceRichtext.new( - stripped_body: "foo" - ) - end - - it "should be not searchable" do - expect(essence_richtext.searchable?).to be(false) - end - end - end -end diff --git a/spec/models/essence_text_spec.rb b/spec/models/essence_text_spec.rb deleted file mode 100644 index 38d2f16..0000000 --- a/spec/models/essence_text_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -require "spec_helper" - -describe Alchemy::EssenceText do - let(:element) do - page_version = create(:alchemy_page_version, :published) - create(:alchemy_element, :with_contents, name: "essence_test", public: true, page_version: page_version) - end - let(:essence_text) do - essence = element.content_by_name("essence_text").essence - essence.body = "foo" - essence - end - - context "searchable?" do - context "content and essence_text are searchable" do - it "should be searchable" do - expect(essence_text.searchable?).to be(true) - end - end - - context "essence_text has no content" do - it "should be not searchable" do - essence_text.body = nil - expect(essence_text.searchable?).to be(false) - end - end - - context "element is not public" do - it "should be not searchable" do - element.public = false - expect(essence_text.searchable?).to be(false) - end - end - - context "essence_text has no related content" do - let(:essence_text) { create(:alchemy_essence_text) } - - it "should be not searchable" do - expect(essence_text.searchable?).to be(false) - end - end - end -end diff --git a/spec/models/ingredient_spec.rb b/spec/models/ingredient_spec.rb index bb07aee..7a1e569 100644 --- a/spec/models/ingredient_spec.rb +++ b/spec/models/ingredient_spec.rb @@ -65,7 +65,7 @@ context "configured as not searchable" do before do - expect_any_instance_of(ingredient.class).to receive(:definition).at_least(:once) do + allow_any_instance_of(ingredient.class).to receive(:definition).at_least(:once) do { searchable: false, } @@ -88,7 +88,7 @@ describe Alchemy::Ingredient do let(:element) do page_version = create(:alchemy_page_version, :published) - create(:alchemy_element, :with_contents, name: "ingredient_test", public: true, page_version: page_version) + create(:alchemy_element, :with_ingredients, name: "ingredient_test", public: true, page_version: page_version) end let(:content) { "foo bar"} @@ -102,7 +102,6 @@ describe Alchemy::Ingredients::Richtext do let(:ingredient) { create(:alchemy_ingredient_richtext, value: content, element: element) } - let(:ingredient_class) { Alchemy::Ingredients::Text } it_behaves_like "it is searchable" it_behaves_like "it is in search index" From c4daab0aa110acc7fd97aa605966f0eae52311d2 Mon Sep 17 00:00:00 2001 From: Sascha Karnatz Date: Mon, 24 Jul 2023 15:18:10 +0200 Subject: [PATCH 5/6] Update to Alchemy 7.0 Update to the latest version of Alchemy. Only newer Alchemy versions are supported. Also remove Webpacker from dummy app (which is the default in Alchemy 7.0). --- Gemfile | 6 +- alchemy-pg_search.gemspec | 2 +- .../app/javascript/packs/alchemy/admin.js | 1 - .../dummy/app/javascript/packs/application.js | 18 -- spec/dummy/bin/webpack | 18 -- spec/dummy/bin/webpack-dev-server | 18 -- spec/dummy/config/alchemy/config.yml.defaults | 12 +- spec/dummy/config/webpack/development.js | 5 - spec/dummy/config/webpack/environment.js | 3 - spec/dummy/config/webpack/production.js | 5 - spec/dummy/config/webpack/test.js | 5 - spec/dummy/config/webpacker.yml | 92 ------- ...724074128_alchemy_six_point_one.alchemy.rb | 249 ++++++++++++++++++ ...add_indexes_to_alchemy_pictures.alchemy.rb | 7 + spec/dummy/db/schema.rb | 91 +++---- 15 files changed, 311 insertions(+), 221 deletions(-) delete mode 100644 spec/dummy/app/javascript/packs/alchemy/admin.js delete mode 100644 spec/dummy/app/javascript/packs/application.js delete mode 100755 spec/dummy/bin/webpack delete mode 100755 spec/dummy/bin/webpack-dev-server delete mode 100644 spec/dummy/config/webpack/development.js delete mode 100644 spec/dummy/config/webpack/environment.js delete mode 100644 spec/dummy/config/webpack/production.js delete mode 100644 spec/dummy/config/webpack/test.js delete mode 100644 spec/dummy/config/webpacker.yml create mode 100644 spec/dummy/db/migrate/20230724074128_alchemy_six_point_one.alchemy.rb create mode 100644 spec/dummy/db/migrate/20230724074129_add_indexes_to_alchemy_pictures.alchemy.rb diff --git a/Gemfile b/Gemfile index 54ed4b0..bd60b79 100644 --- a/Gemfile +++ b/Gemfile @@ -3,12 +3,10 @@ source "https://rubygems.org" gemspec gem "rails", "~> 7.0.0" -ENV.fetch("ALCHEMY_BRANCH", "6.1-stable").tap do |branch| - gem "alchemy_cms", github: "AlchemyCMS/alchemy_cms", branch: branch -end +gem "alchemy_cms", "~> 7.0.0" + gem "sassc-rails" gem "sassc", "~> 2.4.0" -gem "webpacker" gem "pg", "~> 1.0" gem "puma" diff --git a/alchemy-pg_search.gemspec b/alchemy-pg_search.gemspec index 713ee97..4830a86 100644 --- a/alchemy-pg_search.gemspec +++ b/alchemy-pg_search.gemspec @@ -16,7 +16,7 @@ Gem::Specification.new do |spec| spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^spec/}) } spec.require_paths = ["lib"] - spec.add_runtime_dependency "alchemy_cms", [">= 6.1", "< 7"] + spec.add_runtime_dependency "alchemy_cms", [">= 7.0", "< 8"] spec.add_runtime_dependency "pg_search", ["~> 2.1"] spec.add_runtime_dependency "pg" diff --git a/spec/dummy/app/javascript/packs/alchemy/admin.js b/spec/dummy/app/javascript/packs/alchemy/admin.js deleted file mode 100644 index 4691676..0000000 --- a/spec/dummy/app/javascript/packs/alchemy/admin.js +++ /dev/null @@ -1 +0,0 @@ -import "@alchemy_cms/admin" diff --git a/spec/dummy/app/javascript/packs/application.js b/spec/dummy/app/javascript/packs/application.js deleted file mode 100644 index 7c3021d..0000000 --- a/spec/dummy/app/javascript/packs/application.js +++ /dev/null @@ -1,18 +0,0 @@ -/* eslint no-console:0 */ -// This file is automatically compiled by Webpack, along with any other files -// present in this directory. You're encouraged to place your actual application logic in -// a relevant structure within app/javascript and only use these pack files to reference -// that code so it'll be compiled. -// -// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate -// layout file, like app/views/layouts/application.html.erb - - -// Uncomment to copy all static images under ../images to the output folder and reference -// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>) -// or the `imagePath` JavaScript helper below. -// -// const images = require.context('../images', true) -// const imagePath = (name) => images(name, true) - -console.log('Hello World from Webpacker') diff --git a/spec/dummy/bin/webpack b/spec/dummy/bin/webpack deleted file mode 100755 index 1031168..0000000 --- a/spec/dummy/bin/webpack +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env ruby - -ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development" -ENV["NODE_ENV"] ||= "development" - -require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", - Pathname.new(__FILE__).realpath) - -require "bundler/setup" - -require "webpacker" -require "webpacker/webpack_runner" - -APP_ROOT = File.expand_path("..", __dir__) -Dir.chdir(APP_ROOT) do - Webpacker::WebpackRunner.run(ARGV) -end diff --git a/spec/dummy/bin/webpack-dev-server b/spec/dummy/bin/webpack-dev-server deleted file mode 100755 index dd96627..0000000 --- a/spec/dummy/bin/webpack-dev-server +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env ruby - -ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development" -ENV["NODE_ENV"] ||= "development" - -require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", - Pathname.new(__FILE__).realpath) - -require "bundler/setup" - -require "webpacker" -require "webpacker/dev_server_runner" - -APP_ROOT = File.expand_path("..", __dir__) -Dir.chdir(APP_ROOT) do - Webpacker::DevServerRunner.run(ARGV) -end diff --git a/spec/dummy/config/alchemy/config.yml.defaults b/spec/dummy/config/alchemy/config.yml.defaults index 1ba57bd..a457f37 100644 --- a/spec/dummy/config/alchemy/config.yml.defaults +++ b/spec/dummy/config/alchemy/config.yml.defaults @@ -66,9 +66,9 @@ items_per_page: 15 # # Example: # - name: some_element -# contents: -# - name: some_picture -# type: EssencePicture +# ingredients: +# - role: some_picture +# type: Picture # settings: # hint: true # crop: true # turns on image cropping @@ -82,7 +82,7 @@ items_per_page: 15 # preprocess_image_resize [String] # Use this option to resize images to the given size when they are uploaded to the image library. Downsizing example: '1000x1000>' (Default nil) # image_output_format [String] # The global image output format setting. (Default +original+) # -# NOTE: You can always override the output format in the settings of your Essence in elements.yml, I.E. {format: 'gif'} +# NOTE: You can always override the output format in the settings of your ingredients in elements.yml, I.E. {format: 'gif'} # output_image_jpg_quality: 85 preprocess_image_resize: @@ -91,7 +91,7 @@ image_output_format: original # This is used by the seeder to create the default site. default_site: name: Default Site - host: '*' + host: "*" # This is the default language when seeding. default_language: @@ -191,7 +191,7 @@ link_target_options: [blank] # === Format matchers # # Named aliases for regular expressions that can be used in various places. -# The most common use case is the format validation of essences, or attribute validations of your individual models. +# The most common use case is the format validation of ingredients, or attribute validations of your individual models. # # == Example: # diff --git a/spec/dummy/config/webpack/development.js b/spec/dummy/config/webpack/development.js deleted file mode 100644 index c5edff9..0000000 --- a/spec/dummy/config/webpack/development.js +++ /dev/null @@ -1,5 +0,0 @@ -process.env.NODE_ENV = process.env.NODE_ENV || 'development' - -const environment = require('./environment') - -module.exports = environment.toWebpackConfig() diff --git a/spec/dummy/config/webpack/environment.js b/spec/dummy/config/webpack/environment.js deleted file mode 100644 index d16d9af..0000000 --- a/spec/dummy/config/webpack/environment.js +++ /dev/null @@ -1,3 +0,0 @@ -const { environment } = require('@rails/webpacker') - -module.exports = environment diff --git a/spec/dummy/config/webpack/production.js b/spec/dummy/config/webpack/production.js deleted file mode 100644 index be0f53a..0000000 --- a/spec/dummy/config/webpack/production.js +++ /dev/null @@ -1,5 +0,0 @@ -process.env.NODE_ENV = process.env.NODE_ENV || 'production' - -const environment = require('./environment') - -module.exports = environment.toWebpackConfig() diff --git a/spec/dummy/config/webpack/test.js b/spec/dummy/config/webpack/test.js deleted file mode 100644 index c5edff9..0000000 --- a/spec/dummy/config/webpack/test.js +++ /dev/null @@ -1,5 +0,0 @@ -process.env.NODE_ENV = process.env.NODE_ENV || 'development' - -const environment = require('./environment') - -module.exports = environment.toWebpackConfig() diff --git a/spec/dummy/config/webpacker.yml b/spec/dummy/config/webpacker.yml deleted file mode 100644 index a6b1465..0000000 --- a/spec/dummy/config/webpacker.yml +++ /dev/null @@ -1,92 +0,0 @@ -# Note: You must restart bin/webpack-dev-server for changes to take effect - -default: &default - source_path: app/javascript - source_entry_path: packs - public_root_path: public - public_output_path: packs - cache_path: tmp/cache/webpacker - webpack_compile_output: true - - # Additional paths webpack should lookup modules - # ['app/assets', 'engine/foo/app/assets'] - additional_paths: [] - - # Reload manifest.json on all requests so we reload latest compiled packs - cache_manifest: false - - # Extract and emit a css file - extract_css: false - - static_assets_extensions: - - .jpg - - .jpeg - - .png - - .gif - - .tiff - - .ico - - .svg - - .eot - - .otf - - .ttf - - .woff - - .woff2 - - extensions: - - .mjs - - .js - - .sass - - .scss - - .css - - .module.sass - - .module.scss - - .module.css - - .png - - .svg - - .gif - - .jpeg - - .jpg - -development: - <<: *default - compile: true - - # Reference: https://webpack.js.org/configuration/dev-server/ - dev_server: - https: false - host: localhost - port: 3035 - public: localhost:3035 - hmr: false - # Inline should be set to true if using HMR - inline: true - overlay: true - compress: true - disable_host_check: true - use_local_ip: false - quiet: false - pretty: false - headers: - 'Access-Control-Allow-Origin': '*' - watch_options: - ignored: '**/node_modules/**' - - -test: - <<: *default - compile: true - - # Compile test packs to a separate directory - public_output_path: packs-test - -production: - <<: *default - - # Production depends on precompilation of packs prior to booting for performance. - compile: false - - # Extract and emit a css file - extract_css: true - - # Cache manifest.json for performance - cache_manifest: true diff --git a/spec/dummy/db/migrate/20230724074128_alchemy_six_point_one.alchemy.rb b/spec/dummy/db/migrate/20230724074128_alchemy_six_point_one.alchemy.rb new file mode 100644 index 0000000..6ec5b47 --- /dev/null +++ b/spec/dummy/db/migrate/20230724074128_alchemy_six_point_one.alchemy.rb @@ -0,0 +1,249 @@ +# frozen_string_literal: true +# This migration comes from alchemy (originally 20230121212637) + +class AlchemySixPointOne < ActiveRecord::Migration[ActiveRecord::Migration.current_version] + def up + unless table_exists?("alchemy_attachments") + create_table "alchemy_attachments" do |t| + t.string "name" + t.string "file_name" + t.string "file_mime_type" + t.integer "file_size" + t.integer "creator_id" + t.integer "updater_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "file_uid" + t.index ["creator_id"], name: "index_alchemy_attachments_on_creator_id" + t.index ["file_uid"], name: "index_alchemy_attachments_on_file_uid" + t.index ["updater_id"], name: "index_alchemy_attachments_on_updater_id" + end + end + + unless table_exists?("alchemy_elements_alchemy_pages") + create_table "alchemy_elements_alchemy_pages", id: false do |t| + t.integer "element_id" + t.integer "page_id" + t.index ["element_id"], name: "index_alchemy_elements_alchemy_pages_on_element_id" + t.index ["page_id"], name: "index_alchemy_elements_alchemy_pages_on_page_id" + end + end + + unless table_exists?("alchemy_folded_pages") + create_table "alchemy_folded_pages" do |t| + t.integer "page_id", null: false + t.integer "user_id", null: false + t.boolean "folded", default: false, null: false + t.index ["page_id", "user_id"], name: "index_alchemy_folded_pages_on_page_id_and_user_id", unique: true + end + end + + unless table_exists?("alchemy_sites") + create_table "alchemy_sites" do |t| + t.string "host" + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "public", default: false, null: false + t.text "aliases" + t.boolean "redirect_to_primary_host", default: false, null: false + t.index ["host", "public"], name: "alchemy_sites_public_hosts_idx" + t.index ["host"], name: "index_alchemy_sites_on_host" + end + end + + unless table_exists?("alchemy_languages") + create_table "alchemy_languages" do |t| + t.string "name" + t.string "language_code" + t.string "frontpage_name" + t.string "page_layout", default: "intro" + t.boolean "public", default: false, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "creator_id" + t.integer "updater_id" + t.boolean "default", default: false, null: false + t.string "country_code", default: "", null: false + t.references "site", null: false, foreign_key: {to_table: :alchemy_sites} + t.string "locale" + t.index ["creator_id"], name: "index_alchemy_languages_on_creator_id" + t.index ["language_code", "country_code"], name: "index_alchemy_languages_on_language_code_and_country_code" + t.index ["language_code"], name: "index_alchemy_languages_on_language_code" + t.index ["updater_id"], name: "index_alchemy_languages_on_updater_id" + end + end + + unless table_exists?("alchemy_legacy_page_urls") + create_table "alchemy_legacy_page_urls" do |t| + t.string "urlname", null: false + t.integer "page_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["page_id"], name: "index_alchemy_legacy_page_urls_on_page_id" + t.index ["urlname"], name: "index_alchemy_legacy_page_urls_on_urlname" + end + end + + unless table_exists?("alchemy_pages") + create_table "alchemy_pages" do |t| + t.string "name" + t.string "urlname" + t.string "title" + t.string "language_code" + t.boolean "language_root", default: false, null: false + t.string "page_layout" + t.text "meta_keywords" + t.text "meta_description" + t.integer "lft" + t.integer "rgt" + t.integer "parent_id" + t.integer "depth" + t.integer "locked_by" + t.boolean "restricted", default: false, null: false + t.boolean "robot_index", default: true, null: false + t.boolean "robot_follow", default: true, null: false + t.boolean "sitemap", default: true, null: false + t.boolean "layoutpage", default: false, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "creator_id" + t.integer "updater_id" + t.references "language", null: false, foreign_key: {to_table: :alchemy_languages} + t.datetime "published_at", precision: nil + t.datetime "locked_at", precision: nil + t.index ["creator_id"], name: "index_alchemy_pages_on_creator_id" + t.index ["locked_at", "locked_by"], name: "index_alchemy_pages_on_locked_at_and_locked_by" + t.index ["parent_id", "lft"], name: "index_pages_on_parent_id_and_lft" + t.index ["rgt"], name: "index_alchemy_pages_on_rgt" + t.index ["updater_id"], name: "index_alchemy_pages_on_updater_id" + t.index ["urlname"], name: "index_pages_on_urlname" + end + end + + unless table_exists?("alchemy_page_versions") + create_table "alchemy_page_versions" do |t| + t.references "page", null: false, foreign_key: {to_table: :alchemy_pages, on_delete: :cascade} + t.datetime "public_on", precision: nil + t.datetime "public_until", precision: nil + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["public_on", "public_until"], name: "index_alchemy_page_versions_on_public_on_and_public_until" + end + end + + unless table_exists?("alchemy_elements") + create_table "alchemy_elements" do |t| + t.string "name" + t.integer "position" + t.boolean "public", default: true, null: false + t.boolean "folded", default: false, null: false + t.boolean "unique", default: false, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "creator_id" + t.integer "updater_id" + t.integer "parent_element_id" + t.boolean "fixed", default: false, null: false + t.references "page_version", null: false, foreign_key: {to_table: :alchemy_page_versions, on_delete: :cascade} + t.index ["creator_id"], name: "index_alchemy_elements_on_creator_id" + t.index ["fixed"], name: "index_alchemy_elements_on_fixed" + t.index ["page_version_id", "parent_element_id"], name: "idx_alchemy_elements_on_page_version_id_and_parent_element_id" + t.index ["page_version_id", "position"], name: "idx_alchemy_elements_on_page_version_id_and_position" + t.index ["updater_id"], name: "index_alchemy_elements_on_updater_id" + end + end + + unless table_exists?("alchemy_ingredients") + create_table "alchemy_ingredients" do |t| + t.references "element", null: false, foreign_key: {to_table: :alchemy_elements, on_delete: :cascade} + t.string "type", null: false + t.string "role", null: false + t.text "value" + if ActiveRecord::Migration.connection.adapter_name.match?(/postgres/i) + t.jsonb :data, default: {} + else + t.json :data + end + t.string "related_object_type" + t.integer "related_object_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["element_id", "role"], name: "index_alchemy_ingredients_on_element_id_and_role", unique: true + t.index ["related_object_id", "related_object_type"], name: "idx_alchemy_ingredient_relation" + t.index ["type"], name: "index_alchemy_ingredients_on_type" + end + end + + unless table_exists?("alchemy_nodes") + create_table "alchemy_nodes" do |t| + t.string "name" + t.string "title" + t.string "url" + t.boolean "nofollow", default: false, null: false + t.boolean "external", default: false, null: false + t.boolean "folded", default: false, null: false + t.integer "parent_id" + t.integer "lft", null: false + t.integer "rgt", null: false + t.integer "depth", default: 0, null: false + t.references "page", foreign_key: {to_table: :alchemy_pages, on_delete: :restrict} + t.references "language", null: false, foreign_key: {to_table: :alchemy_languages} + t.integer "creator_id" + t.integer "updater_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "menu_type", null: false + t.index ["creator_id"], name: "index_alchemy_nodes_on_creator_id" + t.index ["lft"], name: "index_alchemy_nodes_on_lft" + t.index ["parent_id"], name: "index_alchemy_nodes_on_parent_id" + t.index ["rgt"], name: "index_alchemy_nodes_on_rgt" + t.index ["updater_id"], name: "index_alchemy_nodes_on_updater_id" + end + end + + unless table_exists?("alchemy_pictures") + create_table "alchemy_pictures" do |t| + t.string "name" + t.string "image_file_name" + t.integer "image_file_width" + t.integer "image_file_height" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "creator_id" + t.integer "updater_id" + t.string "upload_hash" + t.string "image_file_uid" + t.integer "image_file_size" + t.string "image_file_format" + t.index ["creator_id"], name: "index_alchemy_pictures_on_creator_id" + t.index ["updater_id"], name: "index_alchemy_pictures_on_updater_id" + end + end + + unless table_exists?("alchemy_picture_thumbs") + create_table "alchemy_picture_thumbs" do |t| + t.references "picture", null: false, foreign_key: {to_table: :alchemy_pictures} + t.string "signature", null: false + t.text "uid", null: false + t.index ["signature"], name: "index_alchemy_picture_thumbs_on_signature", unique: true + end + end + end + + def down + drop_table "alchemy_attachments" if table_exists?("alchemy_attachments") + drop_table "alchemy_elements" if table_exists?("alchemy_elements") + drop_table "alchemy_elements_alchemy_pages" if table_exists?("alchemy_elements_alchemy_pages") + drop_table "alchemy_folded_pages" if table_exists?("alchemy_folded_pages") + drop_table "alchemy_ingredients" if table_exists?("alchemy_ingredients") + drop_table "alchemy_languages" if table_exists?("alchemy_languages") + drop_table "alchemy_legacy_page_urls" if table_exists?("alchemy_legacy_page_urls") + drop_table "alchemy_nodes" if table_exists?("alchemy_nodes") + drop_table "alchemy_page_versions" if table_exists?("alchemy_page_versions") + drop_table "alchemy_pages" if table_exists?("alchemy_pages") + drop_table "alchemy_picture_thumbs" if table_exists?("alchemy_picture_thumbs") + drop_table "alchemy_pictures" if table_exists?("alchemy_pictures") + drop_table "alchemy_sites" if table_exists?("alchemy_sites") + end +end diff --git a/spec/dummy/db/migrate/20230724074129_add_indexes_to_alchemy_pictures.alchemy.rb b/spec/dummy/db/migrate/20230724074129_add_indexes_to_alchemy_pictures.alchemy.rb new file mode 100644 index 0000000..cf1b9fa --- /dev/null +++ b/spec/dummy/db/migrate/20230724074129_add_indexes_to_alchemy_pictures.alchemy.rb @@ -0,0 +1,7 @@ +# This migration comes from alchemy (originally 20230505132743) +class AddIndexesToAlchemyPictures < ActiveRecord::Migration[ActiveRecord::Migration.current_version] + def change + add_index :alchemy_pictures, :name, if_not_exists: true + add_index :alchemy_pictures, :image_file_name, if_not_exists: true + end +end diff --git a/spec/dummy/db/schema.rb b/spec/dummy/db/schema.rb index 6cb4cec..619fbb5 100644 --- a/spec/dummy/db/schema.rb +++ b/spec/dummy/db/schema.rb @@ -2,16 +2,15 @@ # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # -# This file is the source Rails uses to define your schema when running `rails -# db:schema:load`. When creating a new database, `rails db:schema:load` tends to +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to # be faster and is potentially less error prone than running all of your # migrations from scratch. Old migrations may fail to apply correctly if those # migrations use external dependencies or application code. # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_01_19_143815) do - +ActiveRecord::Schema[7.0].define(version: 2023_07_24_074129) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -22,8 +21,8 @@ t.integer "file_size" t.bigint "creator_id" t.bigint "updater_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "file_uid" t.index ["creator_id"], name: "index_alchemy_attachments_on_creator_id" t.index ["file_uid"], name: "index_alchemy_attachments_on_file_uid" @@ -33,8 +32,8 @@ create_table "alchemy_cells", id: :serial, force: :cascade do |t| t.integer "page_id", null: false t.string "name" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["page_id"], name: "index_alchemy_cells_on_page_id" end @@ -54,8 +53,8 @@ t.boolean "public", default: true, null: false t.boolean "folded", default: false, null: false t.boolean "unique", default: false, null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.bigint "creator_id" t.bigint "updater_id" t.bigint "parent_element_id" @@ -90,7 +89,7 @@ end create_table "alchemy_essence_dates", force: :cascade do |t| - t.datetime "date" + t.datetime "date", precision: nil end create_table "alchemy_essence_files", force: :cascade do |t| @@ -105,8 +104,8 @@ t.text "body" t.integer "level" t.integer "size" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "alchemy_essence_htmls", force: :cascade do |t| @@ -122,8 +121,8 @@ create_table "alchemy_essence_nodes", force: :cascade do |t| t.bigint "node_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["node_id"], name: "index_alchemy_essence_nodes_on_node_id" end @@ -198,8 +197,8 @@ t.jsonb "data", default: {} t.string "related_object_type" t.bigint "related_object_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["element_id", "role"], name: "index_alchemy_ingredients_on_element_id_and_role", unique: true t.index ["element_id"], name: "index_alchemy_ingredients_on_element_id" t.index ["related_object_id", "related_object_type"], name: "idx_alchemy_ingredient_relation" @@ -212,8 +211,8 @@ t.string "frontpage_name" t.string "page_layout", default: "intro" t.boolean "public", default: false, null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.bigint "creator_id" t.bigint "updater_id" t.boolean "default", default: false, null: false @@ -230,8 +229,8 @@ create_table "alchemy_legacy_page_urls", force: :cascade do |t| t.string "urlname", null: false t.bigint "page_id", null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["page_id"], name: "index_alchemy_legacy_page_urls_on_page_id" t.index ["urlname"], name: "index_alchemy_legacy_page_urls_on_urlname" end @@ -251,8 +250,8 @@ t.bigint "language_id", null: false t.bigint "creator_id" t.bigint "updater_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "menu_type", null: false t.index ["creator_id"], name: "index_alchemy_nodes_on_creator_id" t.index ["language_id"], name: "index_alchemy_nodes_on_language_id" @@ -265,10 +264,10 @@ create_table "alchemy_page_versions", force: :cascade do |t| t.bigint "page_id", null: false - t.datetime "public_on" - t.datetime "public_until" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "public_on", precision: nil + t.datetime "public_until", precision: nil + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["page_id"], name: "index_alchemy_page_versions_on_page_id" t.index ["public_on", "public_until"], name: "index_alchemy_page_versions_on_public_on_and_public_until" end @@ -292,15 +291,15 @@ t.boolean "robot_follow", default: true, null: false t.boolean "sitemap", default: true, null: false t.boolean "layoutpage", default: false, null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.bigint "creator_id" t.bigint "updater_id" t.bigint "language_id", null: false - t.datetime "published_at" - t.datetime "legacy_public_on" - t.datetime "legacy_public_until" - t.datetime "locked_at" + t.datetime "published_at", precision: nil + t.datetime "legacy_public_on", precision: nil + t.datetime "legacy_public_until", precision: nil + t.datetime "locked_at", precision: nil t.boolean "searchable", default: true, null: false t.index ["creator_id"], name: "index_alchemy_pages_on_creator_id" t.index ["language_id"], name: "index_alchemy_pages_on_language_id" @@ -324,8 +323,8 @@ t.string "image_file_name" t.integer "image_file_width" t.integer "image_file_height" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.bigint "creator_id" t.bigint "updater_id" t.string "upload_hash" @@ -333,14 +332,16 @@ t.integer "image_file_size" t.string "image_file_format" t.index ["creator_id"], name: "index_alchemy_pictures_on_creator_id" + t.index ["image_file_name"], name: "index_alchemy_pictures_on_image_file_name" + t.index ["name"], name: "index_alchemy_pictures_on_name" t.index ["updater_id"], name: "index_alchemy_pictures_on_updater_id" end create_table "alchemy_sites", force: :cascade do |t| t.string "host" t.string "name" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "public", default: false, null: false t.text "aliases" t.boolean "redirect_to_primary_host", default: false, null: false @@ -352,8 +353,8 @@ t.integer "tag_id", null: false t.integer "taggable_id", null: false t.string "taggable_type", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["tag_id"], name: "index_gutentag_taggings_on_tag_id" t.index ["taggable_type", "taggable_id", "tag_id"], name: "unique_taggings", unique: true t.index ["taggable_type", "taggable_id"], name: "index_gutentag_taggings_on_taggable_type_and_taggable_id" @@ -361,8 +362,8 @@ create_table "gutentag_tags", id: :serial, force: :cascade do |t| t.string "name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "taggings_count", default: 0, null: false t.index ["name"], name: "index_gutentag_tags_on_name", unique: true t.index ["taggings_count"], name: "index_gutentag_tags_on_taggings_count" @@ -372,8 +373,8 @@ t.text "content" t.string "searchable_type" t.bigint "searchable_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.bigint "page_id" t.index ["page_id"], name: "index_pg_search_documents_on_page_id" t.index ["searchable_type", "searchable_id"], name: "index_pg_search_documents_on_searchable_type_and_searchable_id" @@ -382,8 +383,8 @@ create_table "users", force: :cascade do |t| t.string "name" t.string "alchemy_roles" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_foreign_key "alchemy_contents", "alchemy_elements", column: "element_id", on_update: :cascade, on_delete: :cascade From d64dbac3d91d3c5f751ac1c4e8414e483210c574 Mon Sep 17 00:00:00 2001 From: Sascha Karnatz Date: Mon, 24 Jul 2023 15:22:55 +0200 Subject: [PATCH 6/6] Update Github CI Ruby version to v3.2 Alchemy does not support Ruby versions below 3.0 and the latest version is 3.2. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1c2f972..eb7bdc4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: 2.7 + ruby-version: 3.2 bundler-cache: true - name: Prepare database run: bundle exec rake alchemy:spec:prepare