Монгоидное самореферентное соединение

В настоящее время я работаю над небольшим приложением для Rails 3, помогающим отслеживать работу секретных Санта-Клаусов. Я почти закончил и полностью озадачен, пытаясь разобраться с этой последней проблемой.

У меня есть монгоидный документ Participant, который требует самообъединения, чтобы представить, кто кому должен покупать подарки. Что бы я ни делал, я не могу заставить это работать. Мой код выглядит следующим образом:

# app/models/participant.rb
class Participant
include Mongoid::Document
include Mongoid::Timestamps

field :first_name, :type => String
field :last_name, :type => String
field :email, :type => String
# --snip--

referenced_in :secret_santa, :class_name => "Participant", :inverse_of => :receiver
references_one :receiver, :class_name => "Participant", :inverse_of => :secret_santa

Используя консоль rails, если я устанавливаю какое-либо свойство, оно никогда не отражается на другой стороне соединения, а иногда теряется все вместе после сохранения и перезагрузки. Я уверен, что ответ смотрит мне прямо в лицо, но после нескольких часов пристального взгляда я все еще не могу его увидеть.


person theTRON    schedule 05.12.2010    source источник


Ответы (2)


Это немного сложно. Наличие самореферентных отношений «многие ко многим» на самом деле проще (см. мой ответ на этот вопрос).

Я думаю, что это самый простой способ реализации самореферентных отношений один к одному. Я проверил это в консоли, и это сработало для меня:

class Participant
  include Mongoid::Document
  referenced_in :secret_santa,
                :class_name => 'Participant'

  # define our own methods instead of using references_one
  def receiver
    self.class.where(:secret_santa_id => self.id).first
  end

  def receiver=(some_participant)
    some_participant.update_attributes(:secret_santa_id => self.id)
  end      
end

al  = Participant.create
ed  = Participant.create
gus = Participant.create

al.secret_santa = ed
al.save
ed.receiver == al         # => true

al.receiver = gus
al.save
gus.secret_santa == al    # => true
person bowsersenior    schedule 05.12.2010

Просто чтобы быть в курсе, с mongoid 2+ вы можете оставаться очень близко к ActiveRecord:

class Participant
   include Mongoid::Document
   has_one :secret_santa, :class_name => 'Participant', :inverse_of => :receiver
   belongs_to :receiver,  :class_name => 'Participant', :inverse_of => :secret_santa
end

ХТН.

person ook    schedule 15.03.2012