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

StackOverflow https://stackoverflow.com/questions/3826600

  •  26-09-2019
  •  | 
  •  

Вопрос

Кто-нибудь знает, как сделать полиморфную ассоциацию в 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

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

Спасибо!

Это было полезно?

Решение

От Mongoid Google Group Похоже, это не поддерживается. Вот то Новейшие соответствующие пост Я нашел.

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

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

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

Другие советы

Отвечая на древний пост, но кто-то может найти это полезным.

Теперь есть также полиморфный 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

Рельсы 4+

Вот как вы бы реализовали Полиморфные ассоциации в Монгоидный для 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+ вы можете использовать образец для беспокойства и создать новый модуль, называемый 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top