I have one parent object, Order, that I need to embed one channel object. The thing is, the object that is the channel can be one of N classes within a module called Channels.
I keep getting the following error, because Mongoid can't look up the right class for the relation. How can I essentially tell Mongoid that the class of the :class field can be one of several? Essentially, I won't know until I'm creating the order which of the concrete classes in the Channels module it will need.
(This seems a bit like "reverse polymorphism" since it's the parent that has to handle multiple types, as opposed to the child being embeddable in multiple types of parents.)
My classes are like so:
class Order
# ...
with_options cascade_callbacks: true do |o|
o.embeds_one :channel
# I've tried several combinations of making the child object polymorphic
# using the `as`/`belongs_to` syntax, to no avail
end
# ...
end
module Channels
class Base
embedded_in :order
# lots of code here that all concrete channels share
end
# then there are concrete subclasses of Channels::Base, e.g.
class Channel1 < Channels::Base
# specifics omitted...
end
class Channel2 < Channels::Base
# specifics omitted...
end
end
The error I get when trying to load/save an order in the shell is this: NameError: uninitialized constant Channel
facepalm The solution is very simple and should have been obvious from the error/stack trace:
Channels module) called Channel, oro.embeds_one :channel, class_name: "Channels::Base"Either of these will work and allow me to override the field with the appropriate concrete subclass for my channel.
Error results from the fact that Mongoid is calling #constantize (or equivalent) under the hood, and no base Channel class exists.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With