2010-12-05 3 views
1

Je travaille actuellement sur une petite application Rails 3 pour aider à suivre secrète-santas au travail. Je suis tout sauf fait et complètement perplexe essayant de résoudre ce dernier problème.Mongoid self-referencial rejoindre

J'ai un document mongoid Participant, qui nécessite une auto-jonction pour représenter qui doit acheter des cadeaux pour qui. Peu importe ce que je fais, je ne semble pas être en mesure de faire fonctionner cela. Mon code est le suivant:

# 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 

Utilisation de la console de rails, si je mets une ou l'autre propriété, il n'y a jamais de l'autre côté de la jointure, et parfois perdu tous ensemble après l'enregistrement et le rechargement. Je suis certain que la réponse me flagrante au visage - mais après des heures à regarder, je ne peux toujours pas le voir.

Répondre

1

Celui-là est un peu compliqué. Avoir une relation plusieurs-à-plusieurs autoréférentielle est réellement plus facile (see my answer to this question). Je pense que c'est la façon la plus simple de mettre en œuvre une relation bi-référentielle un-à-un. Je l'ai testé cela dans la console et cela a fonctionné pour moi:

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 
+0

Merci! Cela a fait l'affaire. – theTRON

2

Juste pour rester à jour, avec MongoId 2+ vous pouvez rester très proche de 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 

HTH.