Browse files

Raise NoMetadata error when attempting to persist without metadata. […

…close #2151]
  • Loading branch information...
1 parent 471a238 commit be2bbfc61812e17483550d90bc3e7d7b44c92667 @durran durran committed Jun 30, 2012
View
4 CHANGELOG.md
@@ -7,6 +7,10 @@ For instructions on upgrading to newer versions, visit
### New Features
+* \#2151 When asking for metadata before persistence, Mongoid will now
+ raise a `Mongoid::Errors::NoMetadata` error if the metadata is not
+ present.
+
* \#2147 `Model#becomes` now copies over the embedded documents.
* A new callback has been introduced: `upsert`, which runs when calling
View
14 lib/config/locales/en.yml
@@ -303,6 +303,20 @@ en:
\_\_merge: 'collection-name'\n
\_\_replace: 'collection-name'\n
\_\_reduce: 'collection-name'\n\n"
+ no_metadata:
+ message: "Metadata not found for document of type %{klass}."
+ summary: "Mongoid sets the metadata of a relation on the document
+ when it is either loaded from within the relation, or added to
+ one. The presence of the metadata is required in order to
+ provide various functionality around relations. Most likely you
+ are getting this error because the document is embedded and was
+ attempted to be persisted without being associated with a parent,
+ or the relation was not properly defined."
+ resolution: "Ensure that your relations on the %{klass} model
+ are all properly defined, and that the inverse relations
+ are also properly defined. Embedded relations must have both the
+ parent (embeds_one/embeds_many) and the inverse (embedded_in)
+ present in order to work properly."
no_parent:
message: "Cannot persist embedded document %{klass} without a
parent document."
View
4 lib/mongoid/atomic.rb
@@ -36,7 +36,7 @@ module Atomic
# @since 2.2.0
def add_atomic_pull(document)
document.flagged_for_destroy = true
- (delayed_atomic_pulls[document.metadata.name.to_s] ||= []).push(document)
+ (delayed_atomic_pulls[document.metadata_name.to_s] ||= []).push(document)
end
# Add an atomic unset for the document.
@@ -51,7 +51,7 @@ def add_atomic_pull(document)
# @since 3.0.0
def add_atomic_unset(document)
document.flagged_for_destroy = true
- (delayed_atomic_unsets[document.metadata.name.to_s] ||= []).push(document)
+ (delayed_atomic_unsets[document.metadata_name.to_s] ||= []).push(document)
end
# For array fields these are the pushes that need to happen.
View
1 lib/mongoid/errors.rb
@@ -23,6 +23,7 @@
require "mongoid/errors/no_default_session"
require "mongoid/errors/no_environment"
require "mongoid/errors/no_map_reduce_output"
+require "mongoid/errors/no_metadata"
require "mongoid/errors/no_parent"
require "mongoid/errors/no_session_config"
require "mongoid/errors/no_sessions_config"
View
12 lib/mongoid/errors/no_metadata.rb
@@ -0,0 +1,12 @@
+# encoding: utf-8
+module Mongoid
+ module Errors
+
+ class NoMetadata < MongoidError
+
+ def initialize(klass)
+ super(compose_message("no_metadata", { klass: klass }))
+ end
+ end
+ end
+end
View
2 lib/mongoid/hierarchy.rb
@@ -79,7 +79,7 @@ def parentize(document)
#
# @since 2.0.0.beta.1
def remove_child(child)
- name = child.metadata.name
+ name = child.metadata_name
if child.embedded_one?
remove_ivar(name)
else
View
16 lib/mongoid/relations.rb
@@ -83,6 +83,22 @@ def embedded_one?
metadata && metadata.macro == :embeds_one
end
+ # Get the metadata name for this document. If no metadata was defined
+ # will raise an error.
+ #
+ # @example Get the metadata name.
+ # document.metadata_name
+ #
+ # @raise [ Errors::NoMetadata ] If no metadata is present.
+ #
+ # @return [ Symbol ] The metadata name.
+ #
+ # @since 3.0.0
+ def metadata_name
+ raise Errors::NoMetadata.new(self.class.name) unless metadata
+ metadata.name
+ end
+
# Determine if the document is part of an references_many relation.
#
# @example Is the document in a references many?
View
2 lib/mongoid/relations/bindings/referenced/in.rb
@@ -25,7 +25,7 @@ def bind_one
bind_polymorphic_inverse_type(base, target.class.model_name)
if inverse = metadata.inverse(target)
if set_base_metadata
- bind_inverse_of_field(base, base.metadata.name)
+ bind_inverse_of_field(base, base.metadata_name)
if base.referenced_many?
target.__send__(inverse).push(base) unless Mongoid.using_identity_map?
else
View
2 lib/mongoid/validations/uniqueness.rb
@@ -243,7 +243,7 @@ def to_validate(document, attribute, value)
# @since 2.4.10
def validate_embedded(document, attribute, value)
return if skip_validation?(document)
- relation = document._parent.send(document.metadata.name)
+ relation = document._parent.send(document.metadata_name)
criteria = create_criteria(relation, document, attribute, value)
add_error(document, attribute, value) if criteria.count > 1
end
View
23 spec/mongoid/errors/no_metadata_spec.rb
@@ -0,0 +1,23 @@
+require 'spec_helper'
+
+describe Mongoid::Errors::NoMetadata do
+
+ describe "#message" do
+
+ let(:error) do
+ described_class.new(Address)
+ end
+
+ it "contains the problem in the message" do
+ error.message.should include("Metadata not found for document of type Address.")
+ end
+
+ it "contains the summary in the message" do
+ error.message.should include("Mongoid sets the metadata of a relation on the")
+ end
+
+ it "contains the resolution in the message" do
+ error.message.should include("Ensure that your relations on the Address model")
+ end
+ end
+end

0 comments on commit be2bbfc

Please sign in to comment.