Does anyone know how to do a polymorphic association in Mongoid
that is of the relational favor but not the embedding one.
For instance this is my Ass
From Mongoid Google Group it looks like this is not supported. Here's the newest relevant post I found.
Anyway, this is not to hard to implement manually. Here's my polymorphic link called Subject.
Implementing inverse part of relation might be somewhat more complicated, especially because you will need same code across multiple classes.
class Notification
include Mongoid::Document
include Mongoid::Timestamps
field :type, :type => String
field :subject_type, :type => String
field :subject_id, :type => BSON::ObjectId
referenced_in :sender, :class_name => "User", :inverse_of => :sent_notifications
referenced_in :recipient, :class_name => "User", :inverse_of => :received_notifications
def subject
@subject ||= if subject_type && subject_id
subject_type.constantize.find(subject_id)
end
end
def subject=(subject)
self.subject_type = subject.class.name
self.subject_id = subject.id
end
end
Here's how you would implement Polymorphic Associations in Mongoid for a Comment
model that can belong to both a Post
and Event
model.
The Comment
Model:
class Comment
include Mongoid::Document
belongs_to :commentable, polymorphic: true
# ...
end
Post
/ Event
Models:
class Post
include Mongoid::Document
has_many :comments, as: :commentable
# ...
end
Using Concerns:
In Rails 4+, you can use the Concern pattern and create a new module called commentable
in app/models/concerns
:
module Commentable
extend ActiveSupport::Concern
included do
has_many :comments, as: :commentable
end
end
and just include
this module in your models:
class Post
include Mongoid::Document
include Commentable
# ...
end
Answering to an ancient post, but someone may find it useful.
Now there's also a polymorphic belongs_to
:
class Action
include Mongoid::Document
include Mongoid::Timestamps::Created
field :action, type: Symbol
belongs_to :subject, :polymorphic => true
end
class User
include Mongoid::Document
include Mongoid::Timestamps
field :username, type: String
has_many :actions, :as => :subject
end
class Company
include Mongoid::Document
include Mongoid::Timestamps
field :name, type: String
has_many :actions, :as => :subject
end