Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MONGOID-5734 Custom polymorphic types (backport to 8.1-stable) #5848

Open
wants to merge 3 commits into
base: 8.1-stable
Choose a base branch
from

Conversation

jamis
Copy link
Contributor

@jamis jamis commented Jul 31, 2024

This is a backport of #5845 to 8.1-stable. Please see that PR for full information.

jamis added 2 commits July 31, 2024 15:06
* first pass at a global resolver registry

* tests

* fix problem with interpreting nested attribute data

* need to register subclasses, too

* raise custom exceptions when failing to resolve models

* fix specs to implement functional around(:context)

* trailing white space
@jamis jamis requested a review from comandeo-mongo July 31, 2024 21:21
# Better practice would be to use unique strings instead of class names to
# identify these polymorphic types in the database (e.g. 'dept' instead of
# 'Department::Engineering').
class UnrecognizedModelAlias < MongoidError
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be nice to rename these new errors to include the word Polymorphic in their name, e.g. UnrecognizedPolypmorphicAlias. From their names they sound more generic than they actually are--the code docs indicate they are very specific to polymorphism.

# resolver instance to use when registering the type. If :default, the default
# `ModelResolver` instance will be used. If any other symbol, it must identify a
# previously registered ModelResolver instance.
def identify_as(*aliases, resolver: :default)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about calling this method polymorphic_as instead? indentify_as is quite generic, and may make users think think it has something to do with the _id field (which it does not.)

@@ -50,12 +50,25 @@ def initialize(association, attributes, options)
@attributes = attributes.with_indifferent_access
@association = association
@options = options
@class_name = options[:class_name] ? options[:class_name].constantize : association.klass
@class_name = class_from(options[:class_name])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable should be refactored to be called @klass instead of @class_name, because it's not a name String--its an actual Class object.

# identifier.
#
# @return [ nil | Mongoid::ModelResolver ] the resolver to use
def resolver
Copy link
Contributor

@johnnyshields johnnyshields Aug 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would recommend to rename to polymorphic_resolver or polymorphic_model_resolver because the name resolver is generic and could be used for many things in the context of a relation (for example, "resolving" that the other side of the relation exists in the DB)

#
# @return [ nil | Mongoid::ModelResolver ] the resolver to use
def resolver
@resolver ||= Mongoid::ModelResolver.resolver(@options[:polymorphic])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here ModelResolver --> PolymorphicModelResolver

@johnnyshields
Copy link
Contributor

Jamis this a great feature to have!! Thank you for it, something I've wanted for a long time.

Please see comments, I think clear/specific naming could greatly enhance the developer experience and reduce potential for confusion/conflicts/heartbreak down the line.

@jamis
Copy link
Contributor Author

jamis commented Aug 1, 2024

Hey @johnnyshields! Thanks for taking a look at the PR, and I'm very happy to hear that this is a feature you're excited about.

One reason for the more general naming here is that there is some potential for a future PR to apply these methods to the single-table inheritance system. Mongoid's STI implementation already has some support for customizing the "discriminator", but the API is all private and the naming is a bit obtuse. Centralizing on a single system that can be used for both STI and the polymorphic associations would be better, I think, and in that case, having names that don't restrict us to polymorphic uses would be nice.

@johnnyshields
Copy link
Contributor

johnnyshields commented Aug 1, 2024

Hmmm... STI is just another form of polymorphism, so the name polymorphic_* still works I think.

I would assert that the names you have today are so generic as to be easily confused with things completely unrelated to "polymorphic relations" or "polymorphic collections".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants