From 7e9b107eb26ce88cdda50d9d4ef81f4a2c0c616a Mon Sep 17 00:00:00 2001 From: ellnix Date: Tue, 18 Mar 2025 21:59:13 +0100 Subject: [PATCH 1/9] Configure mongodb testing --- Gemfile | 2 ++ spec/spec_helper.rb | 5 +++++ spec/support/mongoid.yml | 10 ++++++++++ 3 files changed, 17 insertions(+) create mode 100644 spec/support/mongoid.yml diff --git a/Gemfile b/Gemfile index d018867..61fe611 100644 --- a/Gemfile +++ b/Gemfile @@ -15,10 +15,12 @@ end group :test do rails_version = ENV['RAILS_VERSION'] || '7.1' sequel_version = ENV['SEQUEL_VERSION'] ? "~> #{ENV['SEQUEL_VERSION']}" : '>= 4.0' + mongoid_version = ENV['MONGOID_VERSION'] || '9.0' gem 'active_model_serializers' gem 'rails', "~> #{rails_version}" gem 'sequel', sequel_version + gem 'mongoid', "~> #{mongoid_version}" # remove when deprecate rails 6 if Gem::Version.new(rails_version) >= Gem::Version.new('7.0') diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1f92dc5..6a50e92 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -31,6 +31,7 @@ require 'sqlite3' unless defined?(JRUBY_VERSION) require 'logger' require 'sequel' +require 'mongoid' require 'active_model_serializers' require 'byebug' @@ -44,6 +45,8 @@ Dir["#{File.dirname(__FILE__)}/support/*.rb"].each { |file| require file } +Mongoid.load!('spec/support/mongoid.yml') + RSpec.configure do |c| c.mock_with :rspec c.filter_run focus: true @@ -67,5 +70,7 @@ safe_index_list.each do |index| Meilisearch::Rails.client.delete_index(index) end + + Mongoid.default_client.database.drop end end diff --git a/spec/support/mongoid.yml b/spec/support/mongoid.yml new file mode 100644 index 0000000..e15025e --- /dev/null +++ b/spec/support/mongoid.yml @@ -0,0 +1,10 @@ +test: + clients: + default: + database: "<%= "#{ENV['MONGODB_DATABASE'] || '_ms_rails_test'}_#{SecureRandom.hex(8)}" %>" + hosts: + - "<%= ENV['MONGODB_HOST'] || 'localhost:27017' %>" + options: + read: + mode: :primary + max_pool_size: 1 From ca9b5a831d4d207c1cf78383656724ebdd93b485 Mon Sep 17 00:00:00 2001 From: ellnix Date: Tue, 18 Mar 2025 21:59:36 +0100 Subject: [PATCH 2/9] Test MongoDB in CI No special configuration here, a basic copy/paste of the example in https://github.com/marketplace/actions/mongodb-in-github-actions --- .github/workflows/tests.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1060083..619ba72 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,6 +20,7 @@ jobs: matrix: ruby-version: ["3.2", "3.3", "3.4"] rails-version: [6.1, 7.0] + mongodb-version: [8.0] env: RAILS_VERSION: ${{ matrix.rails-version }} name: integration-tests (Rails ${{ matrix.rails-version }} with Ruby ${{ matrix.ruby-version }}) @@ -34,6 +35,10 @@ jobs: bundler-cache: true - name: Meilisearch (latest) setup with Docker run: docker run -d -p 7700:7700 getmeili/meilisearch:latest meilisearch --master-key=masterKey --no-analytics + - name: Start MongoDB + uses: supercharge/mongodb-github-action@1.12.0 + with: + mongodb-version: ${{ matrix.mongodb-version }} - name: Run tests run: bundle exec rspec - name: Upload coverage reports to Codecov From a9c289f48b6b15bb46f70939e310ee7d9dce94ab Mon Sep 17 00:00:00 2001 From: ellnix Date: Tue, 18 Mar 2025 22:12:46 +0100 Subject: [PATCH 3/9] Add basic MongoDB test --- lib/meilisearch-rails.rb | 7 +++++-- spec/integration/mongoid/record_is_created_spec.rb | 11 +++++++++++ spec/support/mongo_models/citizen.rb | 11 +++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 spec/integration/mongoid/record_is_created_spec.rb create mode 100644 spec/support/mongo_models/citizen.rb diff --git a/lib/meilisearch-rails.rb b/lib/meilisearch-rails.rb index 8da8723..8211d36 100644 --- a/lib/meilisearch-rails.rb +++ b/lib/meilisearch-rails.rb @@ -482,7 +482,8 @@ def meilisearch(options = {}, &block) super(*args) end end - elsif respond_to?(:after_destroy) + # Currently after_destroy_commit is broken in Mongoid + elsif respond_to?(:after_destroy) && !Utilities.mongo_model?(self) after_destroy_commit { |searchable| searchable.ms_enqueue_remove_from_index!(ms_synchronous?) } end end @@ -696,6 +697,8 @@ def ms_search(query, params = {}) # respond with a valid database column. The blocks below prevent that from happening. has_virtual_column_as_pk = if defined?(::Sequel::Model) && self < Sequel::Model meilisearch_options[:type].columns.map(&:to_s).exclude?(condition_key.to_s) + elsif Utilities.mongo_model?(self) + fields.keys.exclude?(condition_key.to_s) else meilisearch_options[:type].columns.map(&:name).map(&:to_s).exclude?(condition_key.to_s) end @@ -784,7 +787,7 @@ def ms_must_reindex?(document) def ms_primary_key_method(options = nil) options ||= meilisearch_options - options[:primary_key] || options[:id] || :id + options[:primary_key] || options[:id] || (Utilities.mongo_model?(self) ? :_id : :id) end protected diff --git a/spec/integration/mongoid/record_is_created_spec.rb b/spec/integration/mongoid/record_is_created_spec.rb new file mode 100644 index 0000000..e4f8e38 --- /dev/null +++ b/spec/integration/mongoid/record_is_created_spec.rb @@ -0,0 +1,11 @@ +require 'support/mongo_models/citizen' + +describe 'MongoDB record is created' do + it 'is added to meilisearch' do + john_wick = Citizen.create(name: 'John Wick', age: 40) + + AsyncHelper.await_last_task + + expect(Citizen.search('John')).to eq([john_wick]) + end +end diff --git a/spec/support/mongo_models/citizen.rb b/spec/support/mongo_models/citizen.rb new file mode 100644 index 0000000..aed0968 --- /dev/null +++ b/spec/support/mongo_models/citizen.rb @@ -0,0 +1,11 @@ +class Citizen + include Mongoid::Document + include Mongoid::Timestamps + + field :name, type: String + field :age, type: Integer + + include MeiliSearch::Rails + + meilisearch index_uid: safe_index_uid('Citizen') +end From be6869e259cee0b2f805680994f293dce3b70783 Mon Sep 17 00:00:00 2001 From: ellnix Date: Tue, 18 Mar 2025 22:17:46 +0100 Subject: [PATCH 4/9] Make rubocop happy --- .rubocop_todo.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 418e8ae..5cc9c61 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,12 +1,12 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2025-03-24 19:18:19 UTC using RuboCop version 1.27.0. +# on 2025-03-28 20:11:18 UTC using RuboCop version 1.27.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 1 +# Offense count: 2 # This cop supports safe auto-correction (--auto-correct). # Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include. # Include: **/*.gemfile, **/Gemfile, **/gems.rb @@ -66,10 +66,10 @@ Lint/UnusedMethodArgument: Exclude: - 'lib/meilisearch-rails.rb' -# Offense count: 15 +# Offense count: 17 # Configuration parameters: IgnoredMethods, CountRepeatedAttributes. Metrics/AbcSize: - Max: 105 + Max: 108 # Offense count: 1 # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods. @@ -82,10 +82,10 @@ Metrics/BlockLength: Metrics/ClassLength: Max: 171 -# Offense count: 11 +# Offense count: 12 # Configuration parameters: IgnoredMethods. Metrics/CyclomaticComplexity: - Max: 28 + Max: 29 # Offense count: 23 # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods. @@ -95,12 +95,12 @@ Metrics/MethodLength: # Offense count: 1 # Configuration parameters: CountComments, CountAsOne. Metrics/ModuleLength: - Max: 437 + Max: 439 -# Offense count: 9 +# Offense count: 10 # Configuration parameters: IgnoredMethods. Metrics/PerceivedComplexity: - Max: 35 + Max: 36 # Offense count: 1 Naming/AccessorMethodName: @@ -139,7 +139,7 @@ RSpec/ContextWording: - 'spec/options_spec.rb' - 'spec/system/tech_shop_spec.rb' -# Offense count: 72 +# Offense count: 74 # Configuration parameters: CountAsOne. RSpec/ExampleLength: Max: 16 @@ -167,7 +167,7 @@ RSpec/MultipleDescribes: Exclude: - 'spec/search_spec.rb' -# Offense count: 3 +# Offense count: 5 RSpec/NestedGroups: Max: 4 @@ -241,7 +241,7 @@ Style/StringLiterals: Exclude: - 'spec/ms_clean_up_job_spec.rb' -# Offense count: 20 +# Offense count: 22 # This cop supports safe auto-correction (--auto-correct). # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https From de30f4e08879105230d5716bc582c3aef73a123f Mon Sep 17 00:00:00 2001 From: ellnix Date: Sat, 22 Mar 2025 19:25:15 +0100 Subject: [PATCH 5/9] Configure mongoid inline --- spec/spec_helper.rb | 16 +++++++++++++++- spec/support/mongoid.yml | 10 ---------- 2 files changed, 15 insertions(+), 11 deletions(-) delete mode 100644 spec/support/mongoid.yml diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 6a50e92..e1ee104 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -45,7 +45,21 @@ Dir["#{File.dirname(__FILE__)}/support/*.rb"].each { |file| require file } -Mongoid.load!('spec/support/mongoid.yml') +mongo_db_name = (ENV['MONGODB_DATABASE'] || '_ms_rails_test') + SecureRandom.hex(8) +Mongoid.load_configuration( + { + clients: { + default: { + database: mongo_db_name, + hosts: [ENV['MONGODB_HOST'] || 'localhost:27017'], + options: { + read: { mode: :primary }, + max_pool_size: 1 + } + } + } + } +) RSpec.configure do |c| c.mock_with :rspec diff --git a/spec/support/mongoid.yml b/spec/support/mongoid.yml deleted file mode 100644 index e15025e..0000000 --- a/spec/support/mongoid.yml +++ /dev/null @@ -1,10 +0,0 @@ -test: - clients: - default: - database: "<%= "#{ENV['MONGODB_DATABASE'] || '_ms_rails_test'}_#{SecureRandom.hex(8)}" %>" - hosts: - - "<%= ENV['MONGODB_HOST'] || 'localhost:27017' %>" - options: - read: - mode: :primary - max_pool_size: 1 From 19b26fbf1488b0fea669dd7087a443c1cf13dfcd Mon Sep 17 00:00:00 2001 From: ellnix Date: Sat, 22 Mar 2025 19:27:11 +0100 Subject: [PATCH 6/9] Move Mongo test config to support file --- spec/spec_helper.rb | 16 ---------------- spec/support/mongoid_config.rb | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 16 deletions(-) create mode 100644 spec/support/mongoid_config.rb diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e1ee104..b6e622b 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -45,22 +45,6 @@ Dir["#{File.dirname(__FILE__)}/support/*.rb"].each { |file| require file } -mongo_db_name = (ENV['MONGODB_DATABASE'] || '_ms_rails_test') + SecureRandom.hex(8) -Mongoid.load_configuration( - { - clients: { - default: { - database: mongo_db_name, - hosts: [ENV['MONGODB_HOST'] || 'localhost:27017'], - options: { - read: { mode: :primary }, - max_pool_size: 1 - } - } - } - } -) - RSpec.configure do |c| c.mock_with :rspec c.filter_run focus: true diff --git a/spec/support/mongoid_config.rb b/spec/support/mongoid_config.rb new file mode 100644 index 0000000..e61050f --- /dev/null +++ b/spec/support/mongoid_config.rb @@ -0,0 +1,15 @@ +mongo_db_name = (ENV['MONGODB_DATABASE'] || '_ms_rails_test') + SecureRandom.hex(8) +Mongoid.load_configuration( + { + clients: { + default: { + database: mongo_db_name, + hosts: [ENV['MONGODB_HOST'] || 'localhost:27017'], + options: { + read: { mode: :primary }, + max_pool_size: 1 + } + } + } + } +) From 5a78e6e35f9fd77a1c2b9afb67e64aa29b617d7d Mon Sep 17 00:00:00 2001 From: ellnix Date: Fri, 28 Mar 2025 21:15:14 +0100 Subject: [PATCH 7/9] Use after_commit instead of after_destroy_commit The bugfix on Mongoid is not released yet, but that should not matter since there is no real reason to turn this back to after_destroy_commit. The behavior is equivalent. --- lib/meilisearch-rails.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/meilisearch-rails.rb b/lib/meilisearch-rails.rb index 8211d36..3fb47b7 100644 --- a/lib/meilisearch-rails.rb +++ b/lib/meilisearch-rails.rb @@ -482,9 +482,8 @@ def meilisearch(options = {}, &block) super(*args) end end - # Currently after_destroy_commit is broken in Mongoid - elsif respond_to?(:after_destroy) && !Utilities.mongo_model?(self) - after_destroy_commit { |searchable| searchable.ms_enqueue_remove_from_index!(ms_synchronous?) } + elsif respond_to?(:after_destroy) + after_commit(on: :destroy) { |searchable| searchable.ms_enqueue_remove_from_index!(ms_synchronous?) } end end end From ab19423ce1b6a26a5c995a6f9d9abbe7bc9e08ec Mon Sep 17 00:00:00 2001 From: ellnix Date: Wed, 2 Apr 2025 15:14:25 +0200 Subject: [PATCH 8/9] Decouple test models from ActiveRecord Intention is to allow testing multiple ORMs more easily, with equivalent data. --- spec/spec_helper.rb | 1 + spec/support/3_model_specification.rb | 13 ++++++++ spec/support/4_active_record_helper.rb | 45 ++++++++++++++++++++++++++ spec/support/active_record_schema.rb | 30 ----------------- 4 files changed, 59 insertions(+), 30 deletions(-) create mode 100644 spec/support/3_model_specification.rb create mode 100644 spec/support/4_active_record_helper.rb delete mode 100644 spec/support/active_record_schema.rb diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b6e622b..4c5b5bd 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -44,6 +44,7 @@ NEW_RAILS = Gem.loaded_specs['rails'].version >= Gem::Version.new('6.0') Dir["#{File.dirname(__FILE__)}/support/*.rb"].each { |file| require file } +Dir["#{File.dirname(__FILE__)}/support/test_models/*.rb"].each { |file| require file } RSpec.configure do |c| c.mock_with :rspec diff --git a/spec/support/3_model_specification.rb b/spec/support/3_model_specification.rb new file mode 100644 index 0000000..f160082 --- /dev/null +++ b/spec/support/3_model_specification.rb @@ -0,0 +1,13 @@ +module Models + class ModelSpecification + Field = Data.define(:name, :type) + + attr_reader :name, :fields, :body + + def initialize(klass_name, fields:, &block) + @name = klass_name + @fields = fields.map { |name, type| Field.new(name, type) } + @body = block + end + end +end diff --git a/spec/support/4_active_record_helper.rb b/spec/support/4_active_record_helper.rb new file mode 100644 index 0000000..b24a573 --- /dev/null +++ b/spec/support/4_active_record_helper.rb @@ -0,0 +1,45 @@ +# This file is responsible for one-time set up of ActiveRecord +# 1 - Set ActiveRecord connection & options +# 2 - Delete existing database +# 3 - Expose "TestModels::ActiveRecord.initialize_model" to allow dynamically creating models +require 'active_record' + +ActiveRecord::Base.logger = Logger.new($stdout) +ActiveRecord::Base.logger.level = Logger::WARN +ActiveRecord::Base.establish_connection( + 'adapter' => defined?(JRUBY_VERSION) ? 'jdbcsqlite3' : 'sqlite3', + 'database' => 'data.sqlite3', + 'pool' => 5, + 'timeout' => 5000 +) + +ActiveRecord::Base.raise_in_transactional_callbacks = true if ActiveRecord::Base.respond_to?(:raise_in_transactional_callbacks) + +FileUtils.rm_f('data.sqlite3') + +module Models + module ActiveRecord + def self.schema + @schema ||= ::ActiveRecord::Schema.new.tap { |schema| schema.verbose = false } + end + + def self.initialize_model(specification) + schema.create_table specification.name.underscore.pluralize do |t| + specification.fields.each do |field| + t.send(field.type, field.name) + end + end + + klass = Class.new(::ActiveRecord::Base) do + define_singleton_method(:model_name) do + name = "Models::ActiveRecord::#{specification.name}" + ActiveModel::Name.new(self, nil, name) + end + end + + const_set(specification.name, klass) + + klass.class_eval(&specification.body) + end + end +end diff --git a/spec/support/active_record_schema.rb b/spec/support/active_record_schema.rb deleted file mode 100644 index 832e021..0000000 --- a/spec/support/active_record_schema.rb +++ /dev/null @@ -1,30 +0,0 @@ -# This file is responsible for one-time set up of ActiveRecord -# 1 - Set ActiveRecord connection & options -# 2 - Delete existing database -# 3 - Expose an "ar_schema" for other files to create tables -require 'active_record' - -ActiveRecord::Base.logger = Logger.new($stdout) -ActiveRecord::Base.logger.level = Logger::WARN -ActiveRecord::Base.establish_connection( - 'adapter' => defined?(JRUBY_VERSION) ? 'jdbcsqlite3' : 'sqlite3', - 'database' => 'data.sqlite3', - 'pool' => 5, - 'timeout' => 5000 -) - -ActiveRecord::Base.raise_in_transactional_callbacks = true if ActiveRecord::Base.respond_to?(:raise_in_transactional_callbacks) - -FileUtils.rm('data.sqlite3') if File.exist?('data.sqlite3') - -unless OLD_RAILS || NEW_RAILS - require 'active_job/test_helper' - - ActiveJob::Base.queue_adapter = :test -end - -def ar_schema - @ar_schema ||= ActiveRecord::Schema.new -end - -ar_schema.verbose = false From 94207741bd79de044c560e06fd932beecc9776d0 Mon Sep 17 00:00:00 2001 From: ellnix Date: Fri, 4 Apr 2025 19:33:28 +0200 Subject: [PATCH 9/9] Make model fixtures generic Make all models in specs generic to allow them to be easily ported to Mongoid and Sequel instead of being stuck on ActiveRecord only. --- spec/support/4_active_record_helper.rb | 12 ++--- spec/support/models/animals.rb | 28 ++++------- spec/support/models/book.rb | 62 ++++++++++++++++++------- spec/support/models/color.rb | 24 ++++------ spec/support/models/disabled_models.rb | 35 +++++++------- spec/support/models/fruit.rb | 13 +++--- spec/support/models/movie.rb | 18 ++----- spec/support/models/people.rb | 24 ++++------ spec/support/models/post.rb | 28 +++++------ spec/support/models/product.rb | 31 +++++++------ spec/support/models/queued_models.rb | 39 +++++++++------- spec/support/models/restaurant.rb | 19 ++++---- spec/support/models/song.rb | 28 ++++++----- spec/support/models/specialty_models.rb | 62 ++++++++++++++----------- spec/support/models/task.rb | 13 +++--- spec/support/models/vegetable.rb | 13 +++--- 16 files changed, 232 insertions(+), 217 deletions(-) diff --git a/spec/support/4_active_record_helper.rb b/spec/support/4_active_record_helper.rb index b24a573..687723a 100644 --- a/spec/support/4_active_record_helper.rb +++ b/spec/support/4_active_record_helper.rb @@ -24,12 +24,6 @@ def self.schema end def self.initialize_model(specification) - schema.create_table specification.name.underscore.pluralize do |t| - specification.fields.each do |field| - t.send(field.type, field.name) - end - end - klass = Class.new(::ActiveRecord::Base) do define_singleton_method(:model_name) do name = "Models::ActiveRecord::#{specification.name}" @@ -40,6 +34,12 @@ def self.initialize_model(specification) const_set(specification.name, klass) klass.class_eval(&specification.body) + + schema.create_table klass.table_name do |t| + specification.fields.each do |field| + t.send(field.type, field.name) + end + end end end end diff --git a/spec/support/models/animals.rb b/spec/support/models/animals.rb index 0534b36..c1e5268 100644 --- a/spec/support/models/animals.rb +++ b/spec/support/models/animals.rb @@ -1,14 +1,9 @@ require 'support/active_record_schema' -ar_schema.create_table :cats do |t| - t.string :name -end - -ar_schema.create_table :dogs do |t| - t.string :name -end - -class Cat < ActiveRecord::Base +cats_specification = Models::ModelSpecification.new( + 'Cat', + fields: [%i[name string]] +) do include Meilisearch::Rails meilisearch index_uid: safe_index_uid('animals'), synchronous: true, primary_key: :ms_id @@ -20,7 +15,10 @@ def ms_id end end -class Dog < ActiveRecord::Base +dogs_specification = Models::ModelSpecification.new( + 'Dog', + fields: [%i[name string]] +) do include Meilisearch::Rails meilisearch index_uid: safe_index_uid('animals'), synchronous: true, primary_key: :ms_id @@ -32,11 +30,5 @@ def ms_id end end -module TestUtil - def self.reset_animals! - Cat.clear_index!(true) - Cat.delete_all - Dog.clear_index!(true) - Dog.delete_all - end -end +Models::ActiveRecord.initialize_model(cats_specification) +Models::ActiveRecord.initialize_model(dogs_specification) diff --git a/spec/support/models/book.rb b/spec/support/models/book.rb index 62a1550..aa7415d 100644 --- a/spec/support/models/book.rb +++ b/spec/support/models/book.rb @@ -1,14 +1,13 @@ -require 'support/active_record_schema' - -ar_schema.create_table :books do |t| - t.string :name - t.string :author - t.boolean :premium - t.boolean :released - t.string :genre -end - -class Book < ActiveRecord::Base +book_specification = Models::ModelSpecification.new( + 'Book', + fields: [ + %i[name string], + %i[author string], + %i[premium boolean], + %i[released boolean], + %i[genre string] + ] +) do include Meilisearch::Rails meilisearch synchronous: true, index_uid: safe_index_uid('SecuredBook'), sanitize: true do @@ -33,10 +32,37 @@ def public? end end -module TestUtil - def self.reset_books! - Book.clear_index!(true) - Book.index(safe_index_uid('BookAuthor')).delete_all_documents - Book.index(safe_index_uid('Book')).delete_all_documents - end -end +Models::ActiveRecord.initialize_model(book_specification) + +# class Book < ActiveRecord::Base +# include Meilisearch::Rails +# +# meilisearch synchronous: true, index_uid: safe_index_uid('SecuredBook'), sanitize: true do +# searchable_attributes [:name] +# typo_tolerance min_word_size_for_typos: { one_typo: 5, twoTypos: 8 } +# filterable_attributes %i[genre author] +# faceting max_values_per_facet: 3 +# +# add_index safe_index_uid('BookAuthor') do +# searchable_attributes [:author] +# end +# +# add_index safe_index_uid('Book'), if: :public? do +# searchable_attributes [:name] +# end +# end +# +# private +# +# def public? +# released && !premium +# end +# end + +# module TestUtil +# def self.reset_books! +# Book.clear_index!(true) +# Book.index(safe_index_uid('BookAuthor')).delete_all_documents +# Book.index(safe_index_uid('Book')).delete_all_documents +# end +# end diff --git a/spec/support/models/color.rb b/spec/support/models/color.rb index 5db25a2..55f7726 100644 --- a/spec/support/models/color.rb +++ b/spec/support/models/color.rb @@ -1,12 +1,11 @@ -require 'support/active_record_schema' - -ar_schema.create_table :colors do |t| - t.string :name - t.string :short_name - t.integer :hex -end - -class Color < ActiveRecord::Base +colors_specification = Models::ModelSpecification.new( + 'Color', + fields: [ + %i[name string], + %i[short_name string], + %i[hex integer] + ] +) do include Meilisearch::Rails attr_accessor :not_indexed @@ -37,9 +36,4 @@ def will_save_change_to_short_name? end end -module TestUtil - def self.reset_colors! - Color.clear_index!(true) - Color.delete_all - end -end +Models::ActiveRecord.initialize_model(colors_specification) diff --git a/spec/support/models/disabled_models.rb b/spec/support/models/disabled_models.rb index 4730ddd..4c3b850 100644 --- a/spec/support/models/disabled_models.rb +++ b/spec/support/models/disabled_models.rb @@ -1,30 +1,29 @@ -require 'support/active_record_schema' - -ar_schema.create_table :disabled_booleans do |t| - t.string :name -end - -ar_schema.create_table :disabled_procs do |t| - t.string :name -end - -ar_schema.create_table :disabled_symbols do |t| - t.string :name -end - -class DisabledBoolean < ActiveRecord::Base +disabled_booleans_specification = Models::ModelSpecification.new( + 'DisabledBoolean', + fields: [%i[name string]] +) do include Meilisearch::Rails meilisearch synchronous: true, disable_indexing: true, index_uid: safe_index_uid('DisabledBoolean') end -class DisabledProc < ActiveRecord::Base +Models::ActiveRecord.initialize_model(disabled_booleans_specification) + +disabled_procs_specification = Models::ModelSpecification.new( + 'DisabledProc', + fields: [%i[name string]] +) do include Meilisearch::Rails meilisearch synchronous: true, disable_indexing: proc { true }, index_uid: safe_index_uid('DisabledProc') end -class DisabledSymbol < ActiveRecord::Base +Models::ActiveRecord.initialize_model(disabled_procs_specification) + +disabled_symbols_specification = Models::ModelSpecification.new( + 'DisabledSymbol', + fields: [%i[name string]] +) do include Meilisearch::Rails meilisearch synchronous: true, disable_indexing: :truth, index_uid: safe_index_uid('DisabledSymbol') @@ -33,3 +32,5 @@ def self.truth true end end + +Models::ActiveRecord.initialize_model(disabled_symbols_specification) diff --git a/spec/support/models/fruit.rb b/spec/support/models/fruit.rb index bd3921f..525e5a3 100644 --- a/spec/support/models/fruit.rb +++ b/spec/support/models/fruit.rb @@ -1,10 +1,7 @@ -require 'support/active_record_schema' - -ar_schema.create_table :fruits do |t| - t.string :name -end - -class Fruit < ActiveRecord::Base +fruits_specification = Models::ModelSpecification.new( + 'Fruit', + fields: [%i[name string]] +) do include Meilisearch::Rails # only raise exceptions in development env @@ -12,3 +9,5 @@ class Fruit < ActiveRecord::Base attribute :name end end + +Models::ActiveRecord.initialize_model(fruits_specification) diff --git a/spec/support/models/movie.rb b/spec/support/models/movie.rb index 28aaf20..e9cf1d2 100644 --- a/spec/support/models/movie.rb +++ b/spec/support/models/movie.rb @@ -1,10 +1,7 @@ -require 'support/active_record_schema' - -ar_schema.create_table :movies do |t| - t.string :title -end - -class Movie < ActiveRecord::Base +movies_specification = Models::ModelSpecification.new( + 'Movie', + fields: [%i[title string]] +) do include Meilisearch::Rails meilisearch index_uid: safe_index_uid('Movie') do @@ -13,9 +10,4 @@ class Movie < ActiveRecord::Base end end -module TestUtil - def self.reset_movies! - Movie.clear_index!(true) - Movie.delete_all - end -end +Models::ActiveRecord.initialize_model(movies_specification) diff --git a/spec/support/models/people.rb b/spec/support/models/people.rb index 9b3c0f5..1c80eb6 100644 --- a/spec/support/models/people.rb +++ b/spec/support/models/people.rb @@ -1,12 +1,11 @@ -require 'support/active_record_schema' - -ar_schema.create_table :people do |t| - t.string :first_name - t.string :last_name - t.integer :card_number -end - -class People < ActiveRecord::Base +people_specification = Models::ModelSpecification.new( + 'People', + fields: [ + %i[first_name string], + %i[last_name string], + %i[card_number integer] + ] +) do include Meilisearch::Rails meilisearch synchronous: true, index_uid: safe_index_uid('MyCustomPeople'), primary_key: :card_number, @@ -23,9 +22,4 @@ def will_save_change_to_full_name? end end -module TestUtil - def self.reset_people! - People.clear_index!(true) - People.delete_all - end -end +Models::ActiveRecord.initialize_model(people_specification) diff --git a/spec/support/models/post.rb b/spec/support/models/post.rb index 7a391b4..72fe600 100644 --- a/spec/support/models/post.rb +++ b/spec/support/models/post.rb @@ -1,15 +1,7 @@ -require 'support/active_record_schema' - -ar_schema.create_table :posts do |t| - t.string :title -end - -ar_schema.create_table :comments do |t| - t.integer :post_id - t.string :body -end - -class Post < ActiveRecord::Base +posts_specification = Models::ModelSpecification.new( + 'Post', + fields: [%i[title string]] +) do has_many :comments include Meilisearch::Rails @@ -23,10 +15,20 @@ class Post < ActiveRecord::Base scope :meilisearch_import, -> { includes(:comments) } end -class Comment < ActiveRecord::Base +Models::ActiveRecord.initialize_model(posts_specification) + +comments_specification = Models::ModelSpecification.new( + 'Comment', + fields: [ + %i[post_id integer], + %i[body string] + ] +) do belongs_to :post include Meilisearch::Rails meilisearch end + +Models::ActiveRecord.initialize_model(comments_specification) diff --git a/spec/support/models/product.rb b/spec/support/models/product.rb index bdafb63..e05ef01 100644 --- a/spec/support/models/product.rb +++ b/spec/support/models/product.rb @@ -1,15 +1,14 @@ -require 'support/active_record_schema' - -ar_schema.create_table :products do |t| - t.string :name - t.string :href - t.string :tags - t.string :type - t.text :description - t.datetime :release_date -end - -class Product < ActiveRecord::Base +products_specification = Models::ModelSpecification.new( + 'Product', + fields: [ + %i[name string], + %i[href string], + %i[tags string], + %i[type string], + %i[description text], + %i[release_date datetime] + ] +) do include Meilisearch::Rails meilisearch auto_index: false, @@ -30,5 +29,11 @@ def published? end end -class Camera < Product +Models::ActiveRecord.initialize_model(products_specification) + +module Models + module ActiveRecord + class Camera < Product + end + end end diff --git a/spec/support/models/queued_models.rb b/spec/support/models/queued_models.rb index 36caa9b..c2ad788 100644 --- a/spec/support/models/queued_models.rb +++ b/spec/support/models/queued_models.rb @@ -1,19 +1,7 @@ -require 'support/active_record_schema' - -ar_schema.create_table :enqueued_documents do |t| - t.string :name -end - -ar_schema.create_table :disabled_enqueued_documents do |t| - t.string :name -end - -ar_schema.create_table :conditionally_enqueued_documents do |t| - t.string :name - t.boolean :is_public -end - -class EnqueuedDocument < ActiveRecord::Base +enqueued_documents_specification = Models::ModelSpecification.new( + 'EnqueuedDocument', + fields: [%i[name string]] +) do include Meilisearch::Rails include GlobalID::Identification @@ -32,7 +20,12 @@ def self.find(_id) end end -class DisabledEnqueuedDocument < ActiveRecord::Base +Models::ActiveRecord.initialize_model(enqueued_documents_specification) + +disabled_enqueued_documents_specification = Models::ModelSpecification.new( + 'DisabledEnqueuedDocument', + fields: [%i[name string]] +) do include Meilisearch::Rails meilisearch(enqueue: proc { |_record| raise 'enqueued' }, @@ -42,7 +35,15 @@ class DisabledEnqueuedDocument < ActiveRecord::Base end end -class ConditionallyEnqueuedDocument < ActiveRecord::Base +Models::ActiveRecord.initialize_model(disabled_enqueued_documents_specification) + +conditionally_enqueued_documents_specification = Models::ModelSpecification.new( + 'ConditionallyEnqueuedDocument', + fields: [ + %i[name string], + %i[is_public boolean] + ] +) do include Meilisearch::Rails meilisearch(enqueue: true, @@ -55,3 +56,5 @@ def should_index? is_public end end + +Models::ActiveRecord.initialize_model(conditionally_enqueued_documents_specification) diff --git a/spec/support/models/restaurant.rb b/spec/support/models/restaurant.rb index e2b6b1b..4522239 100644 --- a/spec/support/models/restaurant.rb +++ b/spec/support/models/restaurant.rb @@ -1,12 +1,11 @@ -require 'support/active_record_schema' - -ar_schema.create_table :restaurants do |t| - t.string :name - t.string :kind - t.text :description -end - -class Restaurant < ActiveRecord::Base +restaurants_specification = Models::ModelSpecification.new( + 'Restaurant', + fields: [ + %i[name string], + %i[kind string], + %i[description text] + ] +) do include GlobalID::Identification include Meilisearch::Rails @@ -16,3 +15,5 @@ class Restaurant < ActiveRecord::Base pagination max_total_hits: 2 end end + +Models::ActiveRecord.initialize_model(restaurants_specification) diff --git a/spec/support/models/song.rb b/spec/support/models/song.rb index d08c71b..c0b4e14 100644 --- a/spec/support/models/song.rb +++ b/spec/support/models/song.rb @@ -1,22 +1,18 @@ -require 'support/active_record_schema' - -ar_schema.create_table :songs do |t| - t.string :name - t.string :artist - t.boolean :released - t.boolean :premium -end - -class Song < ActiveRecord::Base +songs_specification = Models::ModelSpecification.new( + 'Song', + fields: [ + %i[name string], + %i[artist string], + %i[released boolean], + %i[premium boolean] + ] +) do include Meilisearch::Rails - PUBLIC_INDEX_UID = safe_index_uid('Songs') - SECURED_INDEX_UID = safe_index_uid('PrivateSongs') - - meilisearch index_uid: SECURED_INDEX_UID do + meilisearch index_uid: safe_index_uid('PrivateSongs') do searchable_attributes %i[name artist] - add_index PUBLIC_INDEX_UID, if: :public? do + add_index safe_index_uid('Songs'), if: :public? do searchable_attributes %i[name artist] end @@ -29,3 +25,5 @@ def public? released && !premium end end + +Models::ActiveRecord.initialize_model(songs_specification) diff --git a/spec/support/models/specialty_models.rb b/spec/support/models/specialty_models.rb index de20008..bb8a9b8 100644 --- a/spec/support/models/specialty_models.rb +++ b/spec/support/models/specialty_models.rb @@ -1,26 +1,8 @@ -require 'support/active_record_schema' - -ar_schema.create_table :namespaced_models do |t| +Models::ActiveRecord.schema.create_table :namespaced_models do |t| t.string :name t.integer :another_private_value end -ar_schema.create_table :nested_items do |t| - t.integer :parent_id - t.boolean :hidden -end - -ar_schema.create_table :misconfigured_blocks do |t| - t.string :name -end - -ar_schema.create_table :serialized_documents do |t| - t.string :name - t.string :skip -end - -ar_schema.create_table :encoded_strings - module Namespaced def self.table_name_prefix 'namespaced_' @@ -41,7 +23,13 @@ class Model < ActiveRecord::Base end end -class NestedItem < ActiveRecord::Base +nested_items_specification = Models::ModelSpecification.new( + 'NestedItem', + fields: [ + %i[parent_id integer], + %i[hidden boolean] + ] +) do has_many :children, class_name: 'NestedItem', foreign_key: 'parent_id' include Meilisearch::Rails @@ -55,23 +43,43 @@ def nb_children end end -class MisconfiguredBlock < ActiveRecord::Base +Models::ActiveRecord.initialize_model(nested_items_specification) + +misconfigured_blocks_specification = Models::ModelSpecification.new( + 'MisconfiguredBlock', + fields: [%i[name string]] +) do include Meilisearch::Rails end -class SerializedDocumentSerializer < ActiveModel::Serializer - attributes :name +Models::ActiveRecord.initialize_model(misconfigured_blocks_specification) + +module Models + class SerializedDocumentSerializer < ActiveModel::Serializer + attributes :name + end end -class SerializedDocument < ActiveRecord::Base +serialized_documents_specification = Models::ModelSpecification.new( + 'SerializedDocument', + fields: [ + %i[name string], + %i[skip string] + ] +) do include Meilisearch::Rails meilisearch index_uid: safe_index_uid('SerializedDocument') do - use_serializer SerializedDocumentSerializer + use_serializer Models::SerializedDocumentSerializer end end -class EncodedString < ActiveRecord::Base +Models::ActiveRecord.initialize_model(serialized_documents_specification) + +encoded_strings_specification = Models::ModelSpecification.new( + 'EncodedString', + fields: [] +) do include Meilisearch::Rails meilisearch synchronous: true, force_utf8_encoding: true, index_uid: safe_index_uid('EncodedString') do @@ -80,3 +88,5 @@ class EncodedString < ActiveRecord::Base end end end + +Models::ActiveRecord.initialize_model(encoded_strings_specification) diff --git a/spec/support/models/task.rb b/spec/support/models/task.rb index a30da62..7eaf09e 100644 --- a/spec/support/models/task.rb +++ b/spec/support/models/task.rb @@ -1,11 +1,10 @@ -require 'support/active_record_schema' - -ar_schema.create_table :tasks do |t| - t.string :title -end - -class Task < ActiveRecord::Base +tasks_specification = Models::ModelSpecification.new( + 'Task', + fields: [%i[title string]] +) do include Meilisearch::Rails meilisearch synchronous: true, index_uid: safe_index_uid('Task') end + +Models::ActiveRecord.initialize_model(tasks_specification) diff --git a/spec/support/models/vegetable.rb b/spec/support/models/vegetable.rb index f3363e8..b730a5b 100644 --- a/spec/support/models/vegetable.rb +++ b/spec/support/models/vegetable.rb @@ -1,13 +1,12 @@ -require 'support/active_record_schema' - -ar_schema.create_table :vegetables do |t| - t.string :name -end - -class Vegetable < ActiveRecord::Base +vegetables_specification = Models::ModelSpecification.new( + 'Vegetable', + fields: [%i[name string]] +) do include Meilisearch::Rails meilisearch raise_on_failure: false, index_uid: safe_index_uid('Fruit') do attribute :name end end + +Models::ActiveRecord.initialize_model(vegetables_specification)