From ba279bcb852f88bfa2f2dab1c2763d3faceb6c46 Mon Sep 17 00:00:00 2001 From: Neil Shweky Date: Mon, 13 Jul 2020 08:25:58 -0400 Subject: [PATCH 01/10] MONGOID-4921 add discriminator_key as a class variable --- lib/mongoid/traversable.rb | 24 ++++++++- spec/mongoid/traversable_spec.rb | 83 +++++++++++++++++++++++++++++++ spec/support/models/guitar.rb | 5 ++ spec/support/models/instrument.rb | 10 ++++ spec/support/models/piano.rb | 5 ++ 5 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 spec/support/models/guitar.rb create mode 100644 spec/support/models/instrument.rb create mode 100644 spec/support/models/piano.rb diff --git a/lib/mongoid/traversable.rb b/lib/mongoid/traversable.rb index f0042987142..ab4e3d63b3e 100644 --- a/lib/mongoid/traversable.rb +++ b/lib/mongoid/traversable.rb @@ -2,6 +2,10 @@ # encoding: utf-8 module Mongoid + extend self + + attr_accessor :discriminator_key + self.discriminator_key = '_type' # Provides behavior around traversing the document graph. # @@ -17,6 +21,21 @@ def _parent=(p) @__parent = p end + included do + def self.discriminator_key + @discriminator_key || Mongoid.discriminator_key + end + + def self.discriminator_key=(value) + @discriminator_key = value + descendants.each do |child| + child.discriminator_key = value + end + end + + + end + # Get all child +Documents+ to this +Document+, going n levels deep if # necessary. This is used when calling update persistence operations from # the root document, where changes in the entire tree need to be @@ -205,10 +224,11 @@ def inherited(subclass) # We only need the _type field if inheritance is in play, but need to # add to the root class as well for backwards compatibility. unless fields.has_key?("_type") - field(:_type, default: self.name, type: String) + field(self.discriminator_key, default: self.name, type: String) end + subclass_default = subclass.name || ->{ self.class.name } - subclass.field(:_type, default: subclass_default, type: String, overwrite: true) + subclass.field(self.discriminator_key, default: subclass_default, type: String, overwrite: true) end end end diff --git a/spec/mongoid/traversable_spec.rb b/spec/mongoid/traversable_spec.rb index 0004cff9361..42e73e9f7f9 100644 --- a/spec/mongoid/traversable_spec.rb +++ b/spec/mongoid/traversable_spec.rb @@ -251,4 +251,87 @@ end end end + + describe "#discriminator_key" do + + context "when the discriminator key is not changed" do + it "equals _type" do + expect(Instrument.discriminator_key).to eq("_type") + end + + it "children's discriminator keys equal _type" do + expect(Guitar.discriminator_key).to eq("_type") + expect(Piano.discriminator_key).to eq("_type") + end + + it "the base discriminator key is _type" do + expect(Mongoid.discriminator_key).to eq("_type") + end + end + + context "when the discriminator key is changed at the base level" do + before do + Mongoid.discriminator_key = "hello" + end + + after do + Mongoid.discriminator_key = "_type" + end + + it "the value changes" do + expect(Mongoid.discriminator_key).to eq("hello") + end + + it "all discriminator keys change" do + expect(Instrument.discriminator_key).to eq("hello") + expect(Guitar.discriminator_key).to eq("hello") + expect(Piano.discriminator_key).to eq("hello") + end + end + + context "when the discriminator key is changed in the parent" do + before do + Instrument.discriminator_key = "hello2" + end + + after do + Instrument.discriminator_key = "_type" + end + + it "changes in the child classes" do + expect(Guitar.discriminator_key).to eq("hello2") + expect(Piano.discriminator_key).to eq("hello2") + end + + it "the base discriminator key is _type" do + expect(Mongoid.discriminator_key).to eq("_type") + end + end + + context "when the discriminator key is changed in the child" do + before do + Guitar.discriminator_key = "hello3" + end + + after do + Piano.discriminator_key = "_type" + end + + it "changes in the child classes" do + expect(Guitar.discriminator_key).to eq("hello3") + end + + it "doesn't change in the sibling" do + expect(Piano.discriminator_key).to eq("_type") + end + + it "doesn't change in the parent" do + expect(Instrument.discriminator_key).to eq("_type") + end + + it "the base discriminator key is _type" do + expect(Mongoid.discriminator_key).to eq("_type") + end + end + end end diff --git a/spec/support/models/guitar.rb b/spec/support/models/guitar.rb new file mode 100644 index 00000000000..56e66fe1b65 --- /dev/null +++ b/spec/support/models/guitar.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true +# encoding: utf-8 + +class Guitar < Instrument +end \ No newline at end of file diff --git a/spec/support/models/instrument.rb b/spec/support/models/instrument.rb new file mode 100644 index 00000000000..c8092fdb515 --- /dev/null +++ b/spec/support/models/instrument.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true +# encoding: utf-8 + +class Instrument + include Mongoid::Document + field :owner, type: String, default: 0 +end + +require "support/models/guitar" +require "support/models/piano" \ No newline at end of file diff --git a/spec/support/models/piano.rb b/spec/support/models/piano.rb new file mode 100644 index 00000000000..ec094b1a59c --- /dev/null +++ b/spec/support/models/piano.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true +# encoding: utf-8 + +class Piano < Instrument +end \ No newline at end of file From 35d782ecc28599132ac9490f005c58df6c06349e Mon Sep 17 00:00:00 2001 From: Neil Shweky Date: Mon, 13 Jul 2020 08:28:37 -0400 Subject: [PATCH 02/10] MONGOID-4921 clean up code --- lib/mongoid/traversable.rb | 2 -- spec/support/models/guitar.rb | 2 +- spec/support/models/instrument.rb | 2 +- spec/support/models/piano.rb | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/mongoid/traversable.rb b/lib/mongoid/traversable.rb index ab4e3d63b3e..c148eac41dd 100644 --- a/lib/mongoid/traversable.rb +++ b/lib/mongoid/traversable.rb @@ -32,8 +32,6 @@ def self.discriminator_key=(value) child.discriminator_key = value end end - - end # Get all child +Documents+ to this +Document+, going n levels deep if diff --git a/spec/support/models/guitar.rb b/spec/support/models/guitar.rb index 56e66fe1b65..689cc9b9775 100644 --- a/spec/support/models/guitar.rb +++ b/spec/support/models/guitar.rb @@ -2,4 +2,4 @@ # encoding: utf-8 class Guitar < Instrument -end \ No newline at end of file +end diff --git a/spec/support/models/instrument.rb b/spec/support/models/instrument.rb index c8092fdb515..55f95b340c6 100644 --- a/spec/support/models/instrument.rb +++ b/spec/support/models/instrument.rb @@ -7,4 +7,4 @@ class Instrument end require "support/models/guitar" -require "support/models/piano" \ No newline at end of file +require "support/models/piano" diff --git a/spec/support/models/piano.rb b/spec/support/models/piano.rb index ec094b1a59c..af48420456a 100644 --- a/spec/support/models/piano.rb +++ b/spec/support/models/piano.rb @@ -2,4 +2,4 @@ # encoding: utf-8 class Piano < Instrument -end \ No newline at end of file +end From 48bf99089ea333f3d133d8efe253fe2e4578a361 Mon Sep 17 00:00:00 2001 From: Neil Shweky Date: Mon, 13 Jul 2020 10:45:54 -0400 Subject: [PATCH 03/10] MONGOID-4921 add tests, docs --- lib/mongoid.rb | 11 +++++++++++ lib/mongoid/traversable.rb | 8 ++++---- spec/mongoid/traversable_spec.rb | 4 ++-- spec/support/models/guitar.rb | 1 + 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/mongoid.rb b/lib/mongoid.rb index fab4daf08e1..8b5bc4ffbf4 100644 --- a/lib/mongoid.rb +++ b/lib/mongoid.rb @@ -26,6 +26,7 @@ require "mongoid/tasks/database" require "mongoid/query_cache" + # If we are using Rails then we will include the Mongoid railtie. This has all # the nifty initializers that Mongoid needs. if defined?(Rails) @@ -111,4 +112,14 @@ def client(name) # # @since 1.0.0 def_delegators Config, *(Config.public_instance_methods(false) - [ :logger=, :logger ]) + + # The default discriminator key for Mongoid + # + # @example get the base discriminator key + # Mongoid.discriminator_key + # + # @example set the base discriminator key + # Mongoid.discriminator_key = "test" + attr_accessor :discriminator_key + self.discriminator_key = '_type' end diff --git a/lib/mongoid/traversable.rb b/lib/mongoid/traversable.rb index c148eac41dd..7c9b68f1379 100644 --- a/lib/mongoid/traversable.rb +++ b/lib/mongoid/traversable.rb @@ -2,10 +2,6 @@ # encoding: utf-8 module Mongoid - extend self - - attr_accessor :discriminator_key - self.discriminator_key = '_type' # Provides behavior around traversing the document graph. # @@ -28,6 +24,10 @@ def self.discriminator_key def self.discriminator_key=(value) @discriminator_key = value + # unless fields.has_key?(@discriminator_key) + # field(@discriminator_key, default: self.name, type: String) + # end + descendants.each do |child| child.discriminator_key = value end diff --git a/spec/mongoid/traversable_spec.rb b/spec/mongoid/traversable_spec.rb index 42e73e9f7f9..3a1d9668501 100644 --- a/spec/mongoid/traversable_spec.rb +++ b/spec/mongoid/traversable_spec.rb @@ -260,7 +260,7 @@ end it "children's discriminator keys equal _type" do - expect(Guitar.discriminator_key).to eq("_type") + expect(Guitar.discriminator_key).to eq("dkey") expect(Piano.discriminator_key).to eq("_type") end @@ -284,7 +284,7 @@ it "all discriminator keys change" do expect(Instrument.discriminator_key).to eq("hello") - expect(Guitar.discriminator_key).to eq("hello") + expect(Guitar.discriminator_key).to eq("dkey") expect(Piano.discriminator_key).to eq("hello") end end diff --git a/spec/support/models/guitar.rb b/spec/support/models/guitar.rb index 689cc9b9775..0a061ada35a 100644 --- a/spec/support/models/guitar.rb +++ b/spec/support/models/guitar.rb @@ -2,4 +2,5 @@ # encoding: utf-8 class Guitar < Instrument + self.discriminator_key = "dkey" end From 063957813fb80c7d636d4ec9e9b4863494768c23 Mon Sep 17 00:00:00 2001 From: Neil Shweky Date: Mon, 13 Jul 2020 10:47:14 -0400 Subject: [PATCH 04/10] MONGOID-4921 fix whitespace --- lib/mongoid.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/mongoid.rb b/lib/mongoid.rb index 8b5bc4ffbf4..407cd70ba0a 100644 --- a/lib/mongoid.rb +++ b/lib/mongoid.rb @@ -26,7 +26,6 @@ require "mongoid/tasks/database" require "mongoid/query_cache" - # If we are using Rails then we will include the Mongoid railtie. This has all # the nifty initializers that Mongoid needs. if defined?(Rails) From 6ed2d6144d3edbf8e02bb5ef283968d80db10d19 Mon Sep 17 00:00:00 2001 From: Neil Shweky Date: Mon, 13 Jul 2020 12:24:38 -0400 Subject: [PATCH 05/10] MONGOID-4921 update instrument class --- spec/support/models/instrument.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/models/instrument.rb b/spec/support/models/instrument.rb index 55f95b340c6..3b0876b4f29 100644 --- a/spec/support/models/instrument.rb +++ b/spec/support/models/instrument.rb @@ -3,7 +3,7 @@ class Instrument include Mongoid::Document - field :owner, type: String, default: 0 + field :owner, type: String end require "support/models/guitar" From dd8586273e3bd27d33c66b92290f39120567e6f8 Mon Sep 17 00:00:00 2001 From: Neil Shweky Date: Mon, 13 Jul 2020 19:57:18 -0400 Subject: [PATCH 06/10] MONGOID-4921 clean up models; added error; cleaned tests; fixed prepend --- lib/config/locales/en.yml | 7 +++ lib/mongoid/errors.rb | 1 + .../setting_discriminator_key_on_child.rb | 24 ++++++++ lib/mongoid/traversable.rb | 40 +++++++++---- spec/mongoid/traversable_spec.rb | 57 +++++++++---------- spec/support/models/guitar.rb | 1 - spec/support/models/instrument.rb | 1 - 7 files changed, 88 insertions(+), 43 deletions(-) create mode 100644 lib/mongoid/errors/setting_discriminator_key_on_child.rb diff --git a/lib/config/locales/en.yml b/lib/config/locales/en.yml index 7399bd590b8..83fd8b5df00 100644 --- a/lib/config/locales/en.yml +++ b/lib/config/locales/en.yml @@ -502,6 +502,13 @@ en: server versions 3.6 and higher." resolution: "Verify that all servers in your deployment are at least version 3.6 or don't attempt to use sessions with older server versions." + setting_discriminator_key_on_child: + message: "Setting the discriminator key on a child class in not allowed." + summary: "The discriminator key on the class %{class_name} was attempted + to be changed. Changing the discriminator key on a child class is not + allowed." + resolution: "Try setting the discriminator key on %{superclass} or one of %{class_name}'s + ancestors." taken: "is already taken" too_many_nested_attribute_records: diff --git a/lib/mongoid/errors.rb b/lib/mongoid/errors.rb index 7e7a52f608b..2399e258e76 100644 --- a/lib/mongoid/errors.rb +++ b/lib/mongoid/errors.rb @@ -48,6 +48,7 @@ require "mongoid/errors/readonly_attribute" require "mongoid/errors/readonly_document" require "mongoid/errors/scope_overwrite" +require "mongoid/errors/setting_discriminator_key_on_child" require "mongoid/errors/too_many_nested_attribute_records" require "mongoid/errors/unknown_attribute" require "mongoid/errors/unknown_model" diff --git a/lib/mongoid/errors/setting_discriminator_key_on_child.rb b/lib/mongoid/errors/setting_discriminator_key_on_child.rb new file mode 100644 index 00000000000..c1af0673d3d --- /dev/null +++ b/lib/mongoid/errors/setting_discriminator_key_on_child.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true +# encoding: utf-8 + +module Mongoid + module Errors + + # This error is raised when trying to create a scope with an name already + # taken by another scope or method + # + # @example Create the error. + # ScopeOverwrite.new(Person,'teenies') + class SettingDiscriminatorKeyOnChild < MongoidError + def initialize(class_name, superclass) + super( + compose_message( + "setting_discriminator_key_on_child", + { class_name: class_name, superclass: superclass} + ) + ) + end + end + end + end + \ No newline at end of file diff --git a/lib/mongoid/traversable.rb b/lib/mongoid/traversable.rb index 7c9b68f1379..07ba7a76374 100644 --- a/lib/mongoid/traversable.rb +++ b/lib/mongoid/traversable.rb @@ -18,20 +18,36 @@ def _parent=(p) end included do - def self.discriminator_key - @discriminator_key || Mongoid.discriminator_key - end - def self.discriminator_key=(value) - @discriminator_key = value - # unless fields.has_key?(@discriminator_key) - # field(@discriminator_key, default: self.name, type: String) - # end + module DiscriminatorKeyAssignment + def discriminator_key=(value) + if hereditary? + raise Errors::SettingDiscriminatorKeyOnChild.new(self.to_s, self.superclass.to_s) + end - descendants.each do |child| - child.discriminator_key = value + value = Mongoid.discriminator_key unless value + super end end + + class_attribute :discriminator_key, instance_accessor: false + class << self + delegate :discriminator_key, to: ::Mongoid + prepend DiscriminatorKeyAssignment + end + + # def self.discriminator_key + # return @discriminator_key if @discriminator_key + # return superclass.discriminator_key if superclass.respond_to?(:discriminator_key) + # Mongoid.discriminator_key + # end + + # def self.discriminator_key=(value) + # if self.hereditary? + # raise NoMethodError.new "You can only set the discriminator key in the parent" + # end + # @discriminator_key = value + # end end # Get all child +Documents+ to this +Document+, going n levels deep if @@ -222,11 +238,11 @@ def inherited(subclass) # We only need the _type field if inheritance is in play, but need to # add to the root class as well for backwards compatibility. unless fields.has_key?("_type") - field(self.discriminator_key, default: self.name, type: String) + field(:_type, default: self.name, type: String) end subclass_default = subclass.name || ->{ self.class.name } - subclass.field(self.discriminator_key, default: subclass_default, type: String, overwrite: true) + subclass.field(:_type, default: subclass_default, type: String, overwrite: true) end end end diff --git a/spec/mongoid/traversable_spec.rb b/spec/mongoid/traversable_spec.rb index 3a1d9668501..35d2d0a5fe6 100644 --- a/spec/mongoid/traversable_spec.rb +++ b/spec/mongoid/traversable_spec.rb @@ -259,17 +259,17 @@ expect(Instrument.discriminator_key).to eq("_type") end - it "children's discriminator keys equal _type" do - expect(Guitar.discriminator_key).to eq("dkey") - expect(Piano.discriminator_key).to eq("_type") + it "the global discriminator key is _type" do + expect(Mongoid.discriminator_key).to eq("_type") end - it "the base discriminator key is _type" do - expect(Mongoid.discriminator_key).to eq("_type") + it "child discriminator keys equal _type" do + expect(Piano.discriminator_key).to eq("_type") + expect(Guitar.discriminator_key).to eq("_type") end end - - context "when the discriminator key is changed at the base level" do + + context "when the discriminator key is changed at the global level" do before do Mongoid.discriminator_key = "hello" end @@ -284,8 +284,8 @@ it "all discriminator keys change" do expect(Instrument.discriminator_key).to eq("hello") - expect(Guitar.discriminator_key).to eq("dkey") expect(Piano.discriminator_key).to eq("hello") + expect(Guitar.discrdiminator_key).to eq("hello") end end @@ -295,32 +295,35 @@ end after do - Instrument.discriminator_key = "_type" + Instrument.discriminator_key = nil end - it "changes in the child classes" do - expect(Guitar.discriminator_key).to eq("hello2") - expect(Piano.discriminator_key).to eq("hello2") + it "the global discriminator key is _type" do + expect(Mongoid.discriminator_key).to eq("_type") end - it "the base discriminator key is _type" do - expect(Mongoid.discriminator_key).to eq("_type") + it "changes in the child classes" do + expect(Piano.discriminator_key).to eq("hello2") + expect(Guitar.discriminator_key).to eq("hello2") end end context "when the discriminator key is changed in the child" do - before do - Guitar.discriminator_key = "hello3" - end - - after do - Piano.discriminator_key = "_type" - end - - it "changes in the child classes" do - expect(Guitar.discriminator_key).to eq("hello3") + + it "raises an error" do + expect do + Guitar.discriminator_key = "hello3" + end.to raise_error(Mongoid::Errors::SettingDiscriminatorKeyOnChild) + end + + it "doesn't change in that class" do + expect(Guitar.discriminator_key).to eq("_type") + end + + it "the global discriminator key is _type" do + expect(Mongoid.discriminator_key).to eq("_type") end - + it "doesn't change in the sibling" do expect(Piano.discriminator_key).to eq("_type") end @@ -328,10 +331,6 @@ it "doesn't change in the parent" do expect(Instrument.discriminator_key).to eq("_type") end - - it "the base discriminator key is _type" do - expect(Mongoid.discriminator_key).to eq("_type") - end end end end diff --git a/spec/support/models/guitar.rb b/spec/support/models/guitar.rb index 0a061ada35a..689cc9b9775 100644 --- a/spec/support/models/guitar.rb +++ b/spec/support/models/guitar.rb @@ -2,5 +2,4 @@ # encoding: utf-8 class Guitar < Instrument - self.discriminator_key = "dkey" end diff --git a/spec/support/models/instrument.rb b/spec/support/models/instrument.rb index 3b0876b4f29..e3c96db07f6 100644 --- a/spec/support/models/instrument.rb +++ b/spec/support/models/instrument.rb @@ -3,7 +3,6 @@ class Instrument include Mongoid::Document - field :owner, type: String end require "support/models/guitar" From 1390691121779e53bd8022456aed5d29ecaa9455 Mon Sep 17 00:00:00 2001 From: Neil Shweky Date: Mon, 13 Jul 2020 20:23:58 -0400 Subject: [PATCH 07/10] MONGOID-4921 add global discriminator key as config option --- lib/mongoid.rb | 10 ---------- lib/mongoid/config.rb | 3 +++ lib/mongoid/serializable.rb | 2 ++ lib/mongoid/traversable.rb | 14 -------------- spec/mongoid/config_spec.rb | 28 ++++++++++++++++++++++++++++ 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/lib/mongoid.rb b/lib/mongoid.rb index 407cd70ba0a..fab4daf08e1 100644 --- a/lib/mongoid.rb +++ b/lib/mongoid.rb @@ -111,14 +111,4 @@ def client(name) # # @since 1.0.0 def_delegators Config, *(Config.public_instance_methods(false) - [ :logger=, :logger ]) - - # The default discriminator key for Mongoid - # - # @example get the base discriminator key - # Mongoid.discriminator_key - # - # @example set the base discriminator key - # Mongoid.discriminator_key = "test" - attr_accessor :discriminator_key - self.discriminator_key = '_type' end diff --git a/lib/mongoid/config.rb b/lib/mongoid/config.rb index 557a6518b36..e4e1bb2170e 100644 --- a/lib/mongoid/config.rb +++ b/lib/mongoid/config.rb @@ -32,6 +32,9 @@ module Config # error. option :belongs_to_required_by_default, default: true + # Set the global discriminator key. + option :discriminator_key, default: "_type" + # Raise an exception when a field is redefined. option :duplicate_fields_exception, default: false diff --git a/lib/mongoid/serializable.rb b/lib/mongoid/serializable.rb index 245c9d8a94f..eeaabc0b4aa 100644 --- a/lib/mongoid/serializable.rb +++ b/lib/mongoid/serializable.rb @@ -22,6 +22,8 @@ class << self # functionality and not the Ruby standard library one. # See https://jira.mongodb.org/browse/MONGOID-4849. delegate :include_root_in_json, to: ::Mongoid + delegate :discriminator_key, to: ::Mongoid + end end diff --git a/lib/mongoid/traversable.rb b/lib/mongoid/traversable.rb index 07ba7a76374..2e640efc3c9 100644 --- a/lib/mongoid/traversable.rb +++ b/lib/mongoid/traversable.rb @@ -18,7 +18,6 @@ def _parent=(p) end included do - module DiscriminatorKeyAssignment def discriminator_key=(value) if hereditary? @@ -35,19 +34,6 @@ class << self delegate :discriminator_key, to: ::Mongoid prepend DiscriminatorKeyAssignment end - - # def self.discriminator_key - # return @discriminator_key if @discriminator_key - # return superclass.discriminator_key if superclass.respond_to?(:discriminator_key) - # Mongoid.discriminator_key - # end - - # def self.discriminator_key=(value) - # if self.hereditary? - # raise NoMethodError.new "You can only set the discriminator key in the parent" - # end - # @discriminator_key = value - # end end # Get all child +Documents+ to this +Document+, going n levels deep if diff --git a/spec/mongoid/config_spec.rb b/spec/mongoid/config_spec.rb index 9d6c288d177..f40f4ad6611 100644 --- a/spec/mongoid/config_spec.rb +++ b/spec/mongoid/config_spec.rb @@ -197,6 +197,34 @@ end end + context 'when discriminator_key option' do + context 'is not set in the config' do + it 'sets the value to _type by default' do + Mongoid::Config.reset + configuration = CONFIG.merge(options: {}) + + Mongoid.configure { |config| config.load_configuration(configuration) } + + expect(Mongoid::Config.discriminator_key).to be("_type") + end + end + + context 'is set in the config' do + it 'sets the value' do + Mongoid::Config.reset + configuration = CONFIG.merge(options: {discriminator_key: "test"}) + + Mongoid.configure { |config| config.load_configuration(configuration) } + + expect(Mongoid::Config.discriminator_key).to be("test") + end + + it 'is set globally' do + expect(Mongoid.discriminator_key).to be("test") + end + end + end + describe "#load!" do before(:all) do From 99775ecda3d36826f01534446d2e2c595a83e560 Mon Sep 17 00:00:00 2001 From: Neil Shweky Date: Mon, 13 Jul 2020 20:25:49 -0400 Subject: [PATCH 08/10] MONGOID-4921 add discriminator key to the config docs --- docs/tutorials/mongoid-configuration.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/tutorials/mongoid-configuration.txt b/docs/tutorials/mongoid-configuration.txt index d902304b54f..a4a7f625704 100644 --- a/docs/tutorials/mongoid-configuration.txt +++ b/docs/tutorials/mongoid-configuration.txt @@ -245,6 +245,9 @@ can be configured. # error. (default: true) belongs_to_required_by_default: true + # Set the global discriminator key. (default: "_type") + discriminator: "_type" + # Raise an exception when a field is redefined. (default: false) duplicate_fields_exception: false From 7da5e7fba851d074dfb1bf8b78ebdb9985624dfb Mon Sep 17 00:00:00 2001 From: Neil Shweky Date: Mon, 13 Jul 2020 20:30:35 -0400 Subject: [PATCH 09/10] MONGOID-4921 fixed typos, cleaned up code --- docs/tutorials/mongoid-configuration.txt | 2 +- lib/config/locales/en.yml | 2 +- .../setting_discriminator_key_on_child.rb | 31 +++++++++---------- lib/mongoid/serializable.rb | 2 -- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/docs/tutorials/mongoid-configuration.txt b/docs/tutorials/mongoid-configuration.txt index a4a7f625704..3a2d89ecb34 100644 --- a/docs/tutorials/mongoid-configuration.txt +++ b/docs/tutorials/mongoid-configuration.txt @@ -246,7 +246,7 @@ can be configured. belongs_to_required_by_default: true # Set the global discriminator key. (default: "_type") - discriminator: "_type" + discriminator_key: "_type" # Raise an exception when a field is redefined. (default: false) duplicate_fields_exception: false diff --git a/lib/config/locales/en.yml b/lib/config/locales/en.yml index 83fd8b5df00..8e1e168fe6f 100644 --- a/lib/config/locales/en.yml +++ b/lib/config/locales/en.yml @@ -503,7 +503,7 @@ en: resolution: "Verify that all servers in your deployment are at least version 3.6 or don't attempt to use sessions with older server versions." setting_discriminator_key_on_child: - message: "Setting the discriminator key on a child class in not allowed." + message: "Setting the discriminator key on a child class is not allowed." summary: "The discriminator key on the class %{class_name} was attempted to be changed. Changing the discriminator key on a child class is not allowed." diff --git a/lib/mongoid/errors/setting_discriminator_key_on_child.rb b/lib/mongoid/errors/setting_discriminator_key_on_child.rb index c1af0673d3d..8183debd063 100644 --- a/lib/mongoid/errors/setting_discriminator_key_on_child.rb +++ b/lib/mongoid/errors/setting_discriminator_key_on_child.rb @@ -2,23 +2,22 @@ # encoding: utf-8 module Mongoid - module Errors - - # This error is raised when trying to create a scope with an name already - # taken by another scope or method - # - # @example Create the error. - # ScopeOverwrite.new(Person,'teenies') - class SettingDiscriminatorKeyOnChild < MongoidError - def initialize(class_name, superclass) - super( - compose_message( - "setting_discriminator_key_on_child", - { class_name: class_name, superclass: superclass} - ) + module Errors + + # This error is raised when trying to create a scope with an name already + # taken by another scope or method + # + # @example Create the error. + # ScopeOverwrite.new(Person,'teenies') + class SettingDiscriminatorKeyOnChild < MongoidError + def initialize(class_name, superclass) + super( + compose_message( + "setting_discriminator_key_on_child", + { class_name: class_name, superclass: superclass} ) - end + ) end end end - \ No newline at end of file +end diff --git a/lib/mongoid/serializable.rb b/lib/mongoid/serializable.rb index eeaabc0b4aa..245c9d8a94f 100644 --- a/lib/mongoid/serializable.rb +++ b/lib/mongoid/serializable.rb @@ -22,8 +22,6 @@ class << self # functionality and not the Ruby standard library one. # See https://jira.mongodb.org/browse/MONGOID-4849. delegate :include_root_in_json, to: ::Mongoid - delegate :discriminator_key, to: ::Mongoid - end end From db017b53ac54740822fe78794c89021c7cbfec5b Mon Sep 17 00:00:00 2001 From: Neil Shweky Date: Mon, 13 Jul 2020 20:37:30 -0400 Subject: [PATCH 10/10] MONGOID-4921 add test for calling discriminator_key on instance --- spec/mongoid/traversable_spec.rb | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/spec/mongoid/traversable_spec.rb b/spec/mongoid/traversable_spec.rb index 35d2d0a5fe6..e690157ad3f 100644 --- a/spec/mongoid/traversable_spec.rb +++ b/spec/mongoid/traversable_spec.rb @@ -255,6 +255,7 @@ describe "#discriminator_key" do context "when the discriminator key is not changed" do + it "equals _type" do expect(Instrument.discriminator_key).to eq("_type") end @@ -270,6 +271,7 @@ end context "when the discriminator key is changed at the global level" do + before do Mongoid.discriminator_key = "hello" end @@ -285,11 +287,12 @@ it "all discriminator keys change" do expect(Instrument.discriminator_key).to eq("hello") expect(Piano.discriminator_key).to eq("hello") - expect(Guitar.discrdiminator_key).to eq("hello") + expect(Guitar.discriminator_key).to eq("hello") end end context "when the discriminator key is changed in the parent" do + before do Instrument.discriminator_key = "hello2" end @@ -309,7 +312,7 @@ end context "when the discriminator key is changed in the child" do - + it "raises an error" do expect do Guitar.discriminator_key = "hello3" @@ -332,5 +335,24 @@ expect(Instrument.discriminator_key).to eq("_type") end end + + context "when discriminator key is called on an instance" do + + let(:guitar) do + Guitar.new + end + + it "raises an error on setter" do + expect do + guitar.discriminator_key = "hello3" + end.to raise_error(NoMethodError) + end + + it "raises an error on getter" do + expect do + guitar.discriminator_key + end.to raise_error(NoMethodError) + end + end end end