Mongoid Отношения в ActiveSupport :: Модуль Концерна - PullRequest
2 голосов
/ 28 июля 2011

Я пытаюсь создать модуль, который включает полиморфные отношения с Mongoid.Упрощенный пример:

module Scalable
  extend ActiveSupport::Concern

  included do
    references_many :scales, :as => :scalable

    before_save :add_scale
  end

  module InstanceMethods
    def add_scale
      self.scales.create
    end
  end
end

class Scale
  include Mongoid::Document

  referenced_in :scalable, :index => true
end

class ScalableModel
  include Mongoid::Document
  include Scalable
end

Однако, когда я пытаюсь запустить что-то вроде ScalableModel.create, я получаю следующую ошибку:

NoMethodError Exception: undefined method `relations' for Scalable:Module

Это невозможно или я что-то делаюнеправильно?

1 Ответ

2 голосов
/ 28 июля 2011

Я думаю, что связь в модуле (от Scalable до Scale) в порядке, но противоположная половина от Scale до Scalable является проблемой. Это потому, что целевой класс является производным от имени ассоциации, которая ведет Mongoid к модулю Scalable, когда вам действительно нужно сослаться на класс ScalableModel. Затем возникает ошибка, поскольку Mongoid рассматривает модуль как класс модели.

Сначала я подумал, что вам нужно будет определить обе стороны ассоциации в включаемом в Scalable блоке, но оказывается, что вы можете исправить сторону масштаба в ассоциации, пометив ее как полиморфную.

Существует еще одна проблема: self.scale.create вызывает исключение, поскольку вы не можете создать новый дочерний объект, пока его родительский объект не будет сохранен. Чтобы обойти это, я просто использовал after_save. Вот что я придумал:

module Scalable
  extend ActiveSupport::Concern

  included do
    references_many :scales, :as => :scalable
    after_save :add_scale                     # changed from before_save
  end

  module InstanceMethods
    def add_scale
      self.scales.create
    end
  end
end

class Scale
  include Mongoid::Document
  referenced_in :scalable_model, :index => true, :polymorphic => true
end

class ScalableModel1
  include Mongoid::Document
  include Scalable
end

class ScalableModel2
  include Mongoid::Document
  include Scalable
end

s1 = ScalableModel1.create
s2 = ScalableModel2.create
...