Mongoid 8.x多态关联与嵌入模型配置报错求助
问题原因
你在Entity模型中使用embeds_many :custom_fields, as: :item时,Mongoid会默认尝试加载名为CustomField的模型类,但你并没有定义这个类,而是创建了EmailField和MultivalueField两个独立的嵌入模型,因此触发了NameError。
解决方案
要实现多类型嵌入文档,最规范的方式是使用**基类+鉴别器(Discriminator)**的模式,让不同字段类型继承同一个基类,具体代码调整如下:
# 定义自定义字段基类,添加鉴别器支持 class CustomField include Mongoid::Document include Mongoid::Discriminator field :name, type: String embedded_in :item, polymorphic: true end # 邮箱字段继承基类 class EmailField < CustomField field :value, type: String end # 多值字段继承基类 class MultivalueField < CustomField field :value, type: Array end # 实体模型关联基类 class Entity include Mongoid::Document embeds_many :custom_fields, as: :item end
关键说明
- 鉴别器作用:
Mongoid::Discriminator会自动在嵌入的文档中添加_type字段,用来标识具体是EmailField还是MultivalueField,查询时会自动映射到对应的子类。 - 命名空间注意:如果你的模型在
MetadataService::Models命名空间下,需要确保所有模型(包括CustomField)都处于同一命名空间内,避免类查找失败。
使用示例
# 创建包含不同类型字段的实体 entity = Entity.new entity.custom_fields.build(name: "user_email", value: "test@example.com", _type: "EmailField") entity.custom_fields.build(name: "hobbies", value: ["reading", "coding"], _type: "MultivalueField") entity.save # 查询时自动识别类型 entity.custom_fields.each do |field| puts field.class.name # 分别输出 EmailField 和 MultivalueField end
内容的提问来源于stack exchange,提问作者ngw
相关产品推荐
相关产品推荐

