Монгоидная реляционная полиморфная ассоциация

Кто-нибудь знает, как сделать полиморфную ассоциацию в Mongoid, которая имеет реляционную пользу, но не встраивание.

Например, это моя модель Assignment:

class Assignment
  include Mongoid::Document
  include Mongoid::Timestamps

  field :user
  field :due_at, :type => Time

  referenced_in :assignable, :inverse_of => :assignment
end

которые могут иметь полиморфные отношения с несколькими моделями:

class Project
  include Mongoid::Document
  include Mongoid::Timestamps

  field :name, :type => String

  references_many :assignments
end

Это выдает ошибку о том, что неизвестная константа Assignable. Когда я меняю reference на embed, все работает так, как описано в документации Mongoid, но мне нужно, чтобы это было reference.

Спасибо!


person Nik So    schedule 29.09.2010    source источник


Ответы (3)


Из Mongoid Google Group похоже, что это не поддерживается. Вот последнее релевантное сообщение. Я нашел.

В любом случае, это не сложно реализовать вручную. Вот моя полиморфная ссылка под названием Subject.

Реализация обратной части отношения может быть несколько сложнее, особенно потому, что вам потребуется один и тот же код для нескольких классов.

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
person Vojto    schedule 27.12.2010
comment
Поэтому я думаю, что теперь это возможно: группы .google.com/group/mongoid/browse_thread/thread/ - person Vojto; 01.06.2011

Отвечаю на древний пост, но может кому пригодится.

Теперь есть еще и полиморфный 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
person Kimmo Lehto    schedule 05.03.2012

Рельсы 4+

Вот как можно реализовать полиморфные ассоциации в Mongoid для модели Comment, которая может принадлежать как модели Post, так и модели Event.

Модель Comment:

class Comment
  include Mongoid::Document
  belongs_to :commentable, polymorphic: true

  # ...
end

Post / Event Модели:

class Post
  include Mongoid::Document
  has_many :comments, as: :commentable

  # ...
end

Использование проблем:

В Rails 4+ вы можете использовать шаблон Concern и создать новый модуль с именем commentable в app/models/concerns:

module Commentable
  extend ActiveSupport::Concern

  included do
    has_many :comments, as: :commentable
  end
end

и просто include этот модуль в ваших моделях:

class Post
  include Mongoid::Document
  include Commentable

  # ...
end
person Sheharyar    schedule 03.03.2017