From 69116495df259bc5428252b079965c6900c9dab5 Mon Sep 17 00:00:00 2001 From: donquxiote Date: Fri, 25 Feb 2022 15:11:07 -0600 Subject: [PATCH 01/12] take a configurable base class --- lib/acts-as-taggable-on.rb | 5 +++++ lib/acts_as_taggable_on/tag.rb | 2 +- lib/acts_as_taggable_on/tagging.rb | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/acts-as-taggable-on.rb b/lib/acts-as-taggable-on.rb index 4922a181c..8bfadd2cb 100644 --- a/lib/acts-as-taggable-on.rb +++ b/lib/acts-as-taggable-on.rb @@ -79,6 +79,7 @@ def initialize @force_binary_collation = false @tags_table = :tags @taggings_table = :taggings + @base_class = ActiveRecord::Base end def strict_case_match=(force_cs) @@ -119,6 +120,10 @@ def self.apply_binary_collation(bincoll) end end + def self.base_class + Module.const_get("::#{@base_class}") + end + end setup diff --git a/lib/acts_as_taggable_on/tag.rb b/lib/acts_as_taggable_on/tag.rb index 6f6e9d023..390361195 100644 --- a/lib/acts_as_taggable_on/tag.rb +++ b/lib/acts_as_taggable_on/tag.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module ActsAsTaggableOn - class Tag < ::ActiveRecord::Base + class Tag < ActsAsTaggableOn.base_class self.table_name = ActsAsTaggableOn.tags_table ### ASSOCIATIONS: diff --git a/lib/acts_as_taggable_on/tagging.rb b/lib/acts_as_taggable_on/tagging.rb index 1bdb8a575..c8635ef0a 100644 --- a/lib/acts_as_taggable_on/tagging.rb +++ b/lib/acts_as_taggable_on/tagging.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module ActsAsTaggableOn - class Tagging < ::ActiveRecord::Base # :nodoc: + class Tagging < ActsAsTaggableOn.base_class # :nodoc: self.table_name = ActsAsTaggableOn.taggings_table DEFAULT_CONTEXT = 'tags' From 31339b69a84c6e6bf9c4b71f83d0d9d24c1193b7 Mon Sep 17 00:00:00 2001 From: donquxiote Date: Fri, 25 Feb 2022 15:26:59 -0600 Subject: [PATCH 02/12] make base_class instance method --- lib/acts-as-taggable-on.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acts-as-taggable-on.rb b/lib/acts-as-taggable-on.rb index 8bfadd2cb..397520aae 100644 --- a/lib/acts-as-taggable-on.rb +++ b/lib/acts-as-taggable-on.rb @@ -120,7 +120,7 @@ def self.apply_binary_collation(bincoll) end end - def self.base_class + def base_class Module.const_get("::#{@base_class}") end From 536fbd8c9a15035a30ba3db776b52081a67a2962 Mon Sep 17 00:00:00 2001 From: donquxiote Date: Fri, 25 Feb 2022 16:15:27 -0600 Subject: [PATCH 03/12] adds tests --- lib/acts-as-taggable-on.rb | 9 +++++---- spec/acts_as_taggable_on/tag_spec.rb | 5 +++++ spec/acts_as_taggable_on/tagging_spec.rb | 7 +++++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/acts-as-taggable-on.rb b/lib/acts-as-taggable-on.rb index 397520aae..78607d0cc 100644 --- a/lib/acts-as-taggable-on.rb +++ b/lib/acts-as-taggable-on.rb @@ -66,7 +66,7 @@ class Configuration :remove_unused_tags, :default_parser, :tags_counter, :tags_table, :taggings_table - attr_reader :delimiter, :strict_case_match + attr_reader :delimiter, :strict_case_match, :base_class def initialize @delimiter = ',' @@ -79,7 +79,7 @@ def initialize @force_binary_collation = false @tags_table = :tags @taggings_table = :taggings - @base_class = ActiveRecord::Base + @base_class = ::ActiveRecord::Base end def strict_case_match=(force_cs) @@ -120,8 +120,9 @@ def self.apply_binary_collation(bincoll) end end - def base_class - Module.const_get("::#{@base_class}") + def base_class=(base_class) + raise "base_class must be a class constant" unless base_class.is_a?(Class) + @base_class = Module.const_get("::#{base_class}") end end diff --git a/spec/acts_as_taggable_on/tag_spec.rb b/spec/acts_as_taggable_on/tag_spec.rb index b7ba88fdc..f8f1363bb 100644 --- a/spec/acts_as_taggable_on/tag_spec.rb +++ b/spec/acts_as_taggable_on/tag_spec.rb @@ -352,4 +352,9 @@ end end + context "base_class is default" do + it "inherits from ActiveRecord::Base if no base_class is set" do + expect(ActsAsTaggableOn::Tag.ancestors).to include(ActiveRecord::Base) + end + end end diff --git a/spec/acts_as_taggable_on/tagging_spec.rb b/spec/acts_as_taggable_on/tagging_spec.rb index 4efc72cdb..67dcd42e0 100644 --- a/spec/acts_as_taggable_on/tagging_spec.rb +++ b/spec/acts_as_taggable_on/tagging_spec.rb @@ -140,4 +140,11 @@ end end end + + context "base_class is default" do + it "inherits from ActiveRecord::Base if no base_class is set" do + expect(ActsAsTaggableOn::Tagging.ancestors).to include(ActiveRecord::Base) + end + end + end From 1427ab540a1590b9606a204aa4c05466f74540fd Mon Sep 17 00:00:00 2001 From: donquxiote Date: Mon, 28 Feb 2022 10:08:53 -0600 Subject: [PATCH 04/12] adds initializer install rake task --- .../examples/acts_as_taggable_on.rb.example | 3 +++ lib/tasks/install_initializer.rake | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 lib/tasks/examples/acts_as_taggable_on.rb.example create mode 100644 lib/tasks/install_initializer.rake diff --git a/lib/tasks/examples/acts_as_taggable_on.rb.example b/lib/tasks/examples/acts_as_taggable_on.rb.example new file mode 100644 index 000000000..eedcdc466 --- /dev/null +++ b/lib/tasks/examples/acts_as_taggable_on.rb.example @@ -0,0 +1,3 @@ +# require "acts-as-taggable-on" +# ActsAsTaggableOn.base_class = "ApplicationRecord".constantize +# require "acts-as-taggable-on" diff --git a/lib/tasks/install_initializer.rake b/lib/tasks/install_initializer.rake new file mode 100644 index 000000000..e9f24aba9 --- /dev/null +++ b/lib/tasks/install_initializer.rake @@ -0,0 +1,23 @@ +namespace :acts_as_taggable_on do + + namespace :sharded_db do + + desc "Install initializer setting custom base class" + task :install_initializer => [:environment, "config/initializers/foo"] do + source = File.join( + Gem.loaded_specs["acts-as-taggable-on"].full_gem_path, + "lib", + "tasks", + "examples", + "acts_as_taggable_on.rb.example" + ) + + destination = "config/initializers/acts_as_taggable_on.rb" + + cp source, destination + end + + directory "config/initializers" + end + +end From bb2e152abd5ac5b1c53b3177633e9fc4226e77f1 Mon Sep 17 00:00:00 2001 From: donquxiote Date: Mon, 28 Feb 2022 10:12:11 -0600 Subject: [PATCH 05/12] better base_class default --- lib/acts-as-taggable-on.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acts-as-taggable-on.rb b/lib/acts-as-taggable-on.rb index 78607d0cc..f20a215aa 100644 --- a/lib/acts-as-taggable-on.rb +++ b/lib/acts-as-taggable-on.rb @@ -79,7 +79,7 @@ def initialize @force_binary_collation = false @tags_table = :tags @taggings_table = :taggings - @base_class = ::ActiveRecord::Base + @base_class = ActiveRecord::Base end def strict_case_match=(force_cs) From ab634b1414c654be1251f5178213e7be20f72fd4 Mon Sep 17 00:00:00 2001 From: donquxiote Date: Mon, 28 Feb 2022 12:55:26 -0600 Subject: [PATCH 06/12] more sensible default initializer --- lib/tasks/examples/acts_as_taggable_on.rb.example | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/tasks/examples/acts_as_taggable_on.rb.example b/lib/tasks/examples/acts_as_taggable_on.rb.example index eedcdc466..35e8fd01c 100644 --- a/lib/tasks/examples/acts_as_taggable_on.rb.example +++ b/lib/tasks/examples/acts_as_taggable_on.rb.example @@ -1,3 +1,4 @@ -# require "acts-as-taggable-on" -# ActsAsTaggableOn.base_class = "ApplicationRecord".constantize -# require "acts-as-taggable-on" +# This works because the classes where the base class is a concern, Tag and Tagging +# are autoloaded, and won't be started until after the initializers run. + +# ActsAsTaggableOn.base_class = ApplicationRecord From f138dae9a8f4cb2873e842a91aaffa0ac64e9244 Mon Sep 17 00:00:00 2001 From: donquxiote Date: Mon, 28 Feb 2022 14:11:16 -0600 Subject: [PATCH 07/12] add sensible tests --- .../acts_as_taggable_on.rb.example | 0 spec/acts_as_taggable_on/tag_spec.rb | 23 +++++++++++++++++++ spec/acts_as_taggable_on/tagging_spec.rb | 23 +++++++++++++++++++ 3 files changed, 46 insertions(+) rename lib/tasks/{examples => example}/acts_as_taggable_on.rb.example (100%) diff --git a/lib/tasks/examples/acts_as_taggable_on.rb.example b/lib/tasks/example/acts_as_taggable_on.rb.example similarity index 100% rename from lib/tasks/examples/acts_as_taggable_on.rb.example rename to lib/tasks/example/acts_as_taggable_on.rb.example diff --git a/spec/acts_as_taggable_on/tag_spec.rb b/spec/acts_as_taggable_on/tag_spec.rb index f8f1363bb..18b72002e 100644 --- a/spec/acts_as_taggable_on/tag_spec.rb +++ b/spec/acts_as_taggable_on/tag_spec.rb @@ -357,4 +357,27 @@ expect(ActsAsTaggableOn::Tag.ancestors).to include(ActiveRecord::Base) end end + + context "base_class is set" do + before do + class Foo < ActiveRecord::Base; end + ActsAsTaggableOn.base_class = Foo + if defined?(ActsAsTaggableOn::Tag) + hide_const("ActsAsTaggableOn::Tag") + load("lib/acts_as_taggable_on/tag.rb") + end + end + + after do + ActsAsTaggableOn.base_class = ActiveRecord::Base + if defined?(ActsAsTaggableOn::Tag) + hide_const("ActsAsTaggableOn::Tag") + load("lib/acts_as_taggable_on/tag.rb") + end + end + + it "inherits from ActiveRecord::Base if no base_class is set" do + expect(ActsAsTaggableOn::Tag.ancestors).to include(Foo) + end + end end diff --git a/spec/acts_as_taggable_on/tagging_spec.rb b/spec/acts_as_taggable_on/tagging_spec.rb index 67dcd42e0..7e0003f1a 100644 --- a/spec/acts_as_taggable_on/tagging_spec.rb +++ b/spec/acts_as_taggable_on/tagging_spec.rb @@ -147,4 +147,27 @@ end end + context "base_class is set" do + before do + class Foo < ActiveRecord::Base; end + ActsAsTaggableOn.base_class = Foo + if defined?(ActsAsTaggableOn::Tagging) + hide_const("ActsAsTaggableOn::Tagging") + load("lib/acts_as_taggable_on/tagging.rb") + end + end + + after do + ActsAsTaggableOn.base_class = ActiveRecord::Base + if defined?(ActsAsTaggableOn::Tagging) + hide_const("ActsAsTaggableOn::Tagging") + load("lib/acts_as_taggable_on/tagging.rb") + end + end + + it "inherits from ActiveRecord::Base if no base_class is set" do + expect(ActsAsTaggableOn::Tagging.ancestors).to include(Foo) + end + end + end From 371c88ef8bb823efcd0b9cbe4873316d0ac915cd Mon Sep 17 00:00:00 2001 From: donquxiote Date: Mon, 28 Feb 2022 14:54:19 -0600 Subject: [PATCH 08/12] reduce test overhead --- spec/acts_as_taggable_on/tag_spec.rb | 18 +++--------------- spec/acts_as_taggable_on/tagging_spec.rb | 18 +++--------------- 2 files changed, 6 insertions(+), 30 deletions(-) diff --git a/spec/acts_as_taggable_on/tag_spec.rb b/spec/acts_as_taggable_on/tag_spec.rb index 18b72002e..10685e64b 100644 --- a/spec/acts_as_taggable_on/tag_spec.rb +++ b/spec/acts_as_taggable_on/tag_spec.rb @@ -359,24 +359,12 @@ end context "base_class is set" do - before do + it "inherits from ActiveRecord::Base if no base_class is set" do class Foo < ActiveRecord::Base; end ActsAsTaggableOn.base_class = Foo - if defined?(ActsAsTaggableOn::Tag) - hide_const("ActsAsTaggableOn::Tag") - load("lib/acts_as_taggable_on/tag.rb") - end - end + hide_const("ActsAsTaggableOn::Tag") + load("lib/acts_as_taggable_on/tag.rb") - after do - ActsAsTaggableOn.base_class = ActiveRecord::Base - if defined?(ActsAsTaggableOn::Tag) - hide_const("ActsAsTaggableOn::Tag") - load("lib/acts_as_taggable_on/tag.rb") - end - end - - it "inherits from ActiveRecord::Base if no base_class is set" do expect(ActsAsTaggableOn::Tag.ancestors).to include(Foo) end end diff --git a/spec/acts_as_taggable_on/tagging_spec.rb b/spec/acts_as_taggable_on/tagging_spec.rb index 7e0003f1a..b7312c83f 100644 --- a/spec/acts_as_taggable_on/tagging_spec.rb +++ b/spec/acts_as_taggable_on/tagging_spec.rb @@ -148,24 +148,12 @@ end context "base_class is set" do - before do + it "inherits from ActiveRecord::Base if no base_class is set" do class Foo < ActiveRecord::Base; end ActsAsTaggableOn.base_class = Foo - if defined?(ActsAsTaggableOn::Tagging) - hide_const("ActsAsTaggableOn::Tagging") - load("lib/acts_as_taggable_on/tagging.rb") - end - end + hide_const("ActsAsTaggableOn::Tagging") + load("lib/acts_as_taggable_on/tagging.rb") - after do - ActsAsTaggableOn.base_class = ActiveRecord::Base - if defined?(ActsAsTaggableOn::Tagging) - hide_const("ActsAsTaggableOn::Tagging") - load("lib/acts_as_taggable_on/tagging.rb") - end - end - - it "inherits from ActiveRecord::Base if no base_class is set" do expect(ActsAsTaggableOn::Tagging.ancestors).to include(Foo) end end From 05a27e35226f7a12658193bb50577844dc9acef1 Mon Sep 17 00:00:00 2001 From: donquxiote Date: Mon, 28 Feb 2022 15:16:20 -0600 Subject: [PATCH 09/12] updates changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c50a68f11..468c60f70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ As such, _Breaking Changes_ are major. _Features_ would map to either major or m ### [v9.0.2) / unreleased](https://github.com/mbleigh/acts-as-taggable-on/compare/v9.0.1...master) * Features * [@glampr Add support for prefix and suffix searches alongside previously supported containment (wildcard) searches](https://github.com/mbleigh/acts-as-taggable-on/pull/1082) + * [@donquxiote Add support for horizontally sharded databases](https://github.com/mbleigh/acts-as-taggable-on/pull/1079) ### [v9.0.1) / 2022-01-07](https://github.com/mbleigh/acts-as-taggable-on/compare/v9.0.0..v9.0.1) * Fixes From 3998254829bfa431fec999cb68c8ecb2c6956d4f Mon Sep 17 00:00:00 2001 From: donquxiote Date: Tue, 1 Mar 2022 11:35:04 -0600 Subject: [PATCH 10/12] make base_class= simpler --- lib/acts-as-taggable-on.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acts-as-taggable-on.rb b/lib/acts-as-taggable-on.rb index f20a215aa..3f4fd9147 100644 --- a/lib/acts-as-taggable-on.rb +++ b/lib/acts-as-taggable-on.rb @@ -122,7 +122,7 @@ def self.apply_binary_collation(bincoll) def base_class=(base_class) raise "base_class must be a class constant" unless base_class.is_a?(Class) - @base_class = Module.const_get("::#{base_class}") + @base_class = base_class end end From 019e407b326f57a7cc21f9a06c392fa4a95df916 Mon Sep 17 00:00:00 2001 From: donquxiote Date: Tue, 1 Mar 2022 11:35:22 -0600 Subject: [PATCH 11/12] improve test clarity --- spec/acts_as_taggable_on/tag_spec.rb | 30 +++++++++++++++--------- spec/acts_as_taggable_on/tagging_spec.rb | 30 +++++++++++++++--------- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/spec/acts_as_taggable_on/tag_spec.rb b/spec/acts_as_taggable_on/tag_spec.rb index 10685e64b..a916a4a43 100644 --- a/spec/acts_as_taggable_on/tag_spec.rb +++ b/spec/acts_as_taggable_on/tag_spec.rb @@ -352,20 +352,28 @@ end end - context "base_class is default" do - it "inherits from ActiveRecord::Base if no base_class is set" do - expect(ActsAsTaggableOn::Tag.ancestors).to include(ActiveRecord::Base) + describe 'base_class' do + before do + class Foo < ActiveRecord::Base; end end - end - context "base_class is set" do - it "inherits from ActiveRecord::Base if no base_class is set" do - class Foo < ActiveRecord::Base; end - ActsAsTaggableOn.base_class = Foo - hide_const("ActsAsTaggableOn::Tag") - load("lib/acts_as_taggable_on/tag.rb") + context "default" do + it "inherits from ActiveRecord::Base" do + + expect(ActsAsTaggableOn::Tag.ancestors).to include(ActiveRecord::Base) + expect(ActsAsTaggableOn::Tag.ancestors).to_not include(Foo) + end + end + + context "custom" do + it "inherits from custom class" do - expect(ActsAsTaggableOn::Tag.ancestors).to include(Foo) + ActsAsTaggableOn.base_class = Foo + hide_const("ActsAsTaggableOn::Tag") + load("lib/acts_as_taggable_on/tag.rb") + + expect(ActsAsTaggableOn::Tag.ancestors).to include(Foo) + end end end end diff --git a/spec/acts_as_taggable_on/tagging_spec.rb b/spec/acts_as_taggable_on/tagging_spec.rb index b7312c83f..dde37f7f7 100644 --- a/spec/acts_as_taggable_on/tagging_spec.rb +++ b/spec/acts_as_taggable_on/tagging_spec.rb @@ -141,20 +141,28 @@ end end - context "base_class is default" do - it "inherits from ActiveRecord::Base if no base_class is set" do - expect(ActsAsTaggableOn::Tagging.ancestors).to include(ActiveRecord::Base) + describe 'base_class' do + before do + class Foo < ActiveRecord::Base; end end - end - context "base_class is set" do - it "inherits from ActiveRecord::Base if no base_class is set" do - class Foo < ActiveRecord::Base; end - ActsAsTaggableOn.base_class = Foo - hide_const("ActsAsTaggableOn::Tagging") - load("lib/acts_as_taggable_on/tagging.rb") + context "default" do + it "inherits from ActiveRecord::Base" do + + expect(ActsAsTaggableOn::Tagging.ancestors).to include(ActiveRecord::Base) + expect(ActsAsTaggableOn::Tagging.ancestors).to_not include(Foo) + end + end + + context "custom" do + it "inherits from custom class" do - expect(ActsAsTaggableOn::Tagging.ancestors).to include(Foo) + ActsAsTaggableOn.base_class = Foo + hide_const("ActsAsTaggableOn::Tagging") + load("lib/acts_as_taggable_on/tagging.rb") + + expect(ActsAsTaggableOn::Tagging.ancestors).to include(Foo) + end end end From 99331e1d5118e9beda8f621a9f8b508137e52c7a Mon Sep 17 00:00:00 2001 From: donquxiote Date: Tue, 1 Mar 2022 11:55:37 -0600 Subject: [PATCH 12/12] original default class --- lib/acts-as-taggable-on.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acts-as-taggable-on.rb b/lib/acts-as-taggable-on.rb index 3f4fd9147..e7d087420 100644 --- a/lib/acts-as-taggable-on.rb +++ b/lib/acts-as-taggable-on.rb @@ -79,7 +79,7 @@ def initialize @force_binary_collation = false @tags_table = :tags @taggings_table = :taggings - @base_class = ActiveRecord::Base + @base_class = ::ActiveRecord::Base end def strict_case_match=(force_cs)