@@ -1211,43 +1211,60 @@ that a bundle may contain other bundles or products:
12111211 has_many :items, polymorphic: true
12121212 end
12131213
1214- Starting in version 9.0.2, Mongoid allows you to store an arbitrary string in the
1215- `*_type` attribute. This feature allows the class resolution to be handled at
1216- runtime.
1214+ Starting in version 9.0.2, Mongoid adds support to custom polymorphic types via
1215+ a global registry. You can now specify alternative keys to represent different
1216+ classes, thus decoupling the code from the data. For example:
12171217
1218- For example:
1218+ .. code-block:: ruby
1219+
1220+ class Department
1221+ include Mongoid::Document
1222+ identify_as 'dept'
1223+ has_many :managers, as: :unit
1224+ end
1225+
1226+ The ``identify_as 'dept'`` directive says that this class should be identified by
1227+ the string "dept" in the database. You can specify multiple aliases, too (e.g.
1228+ ``entify_as 'dept', 'div', 'agency'``), in which case the first key is the "default",
1229+ and the others are only used for looking up records. This lets you refactor your
1230+ code without breaking the associations in your data.
1231+
1232+ Note that these aliases are global; the keys you specify must be unique across your
1233+ entire code base. However, it is possible to register alternative resolvers, which
1234+ must be used for different subsets of your models. In this case, the keys must
1235+ only be unique for each resolver. For example:
12191236
12201237.. code-block:: ruby
12211238
1222- class Item
1223- include Mongoid::Document
1224- belongs_to :unitable, polymorphic: true, type_field_method:
1225- :resolve_unitable_type
1226- field :unitable_type, type: String
1227-
1228- def resolve_unitable_type(value)
1229- case value
1230- when "warehouse"
1231- Unit
1232- when "store"
1233- Store
1234- else
1235- nil
1236- end
1237- end
1238- end
1239+ Mongoid::ModelResolver.register_resolver Mongoid::ModelResolver.new, :eng
1240+ Mongoid::ModelResolver.register_resolver Mongoid::ModelResolver.new, :purch
12391241
1240- unit = Unit.create(name: "Warehouse")
1241- item = Item.create(unitable_id: unit.id, unitable_type: "warehouse")
1242+ module Engineering
1243+ class Department
1244+ include Mongoid::Document
1245+ identify_as 'dept', resolver: :eng
1246+ end
12421247
1243- store = Store.create(name: "Downtown")
1244- store_item = Item.create(unitable_id: store.id, unitable_type: "store")
1248+ class Manager
1249+ include Mongoid::Document
1250+ belongs_to :unit, polymorphic: :eng
1251+ end
1252+ end
12451253
1246- # Results in
1247- # { "_id": ObjectId("..."), "unitable_id": ObjectId("..."), "unitable_type": "warehouse" }
1248- # { "_id": ObjectId("..."), "unitable_id": ObjectId("..."), "unitable_type": "store" }
1254+ module Purchasing
1255+ class Department
1256+ include Mongoid::Document
1257+ identify_as 'dept', resolver: :purch
1258+ end
12491259
1260+ class Manager
1261+ include Mongoid::Document
1262+ belongs_to :unit, polymorphic: :purch
1263+ end
1264+ end
12501265
1266+ Both ``Engineering::Department`` and ``Purchasing::Department`` are aliased as
1267+ ``"dept"``, but use their own resolver, so there is no conflict.
12511268
12521269``has_and_belongs_to_many`` associations do not support polymorphism.
12531270
0 commit comments