2010-01-21 16 views
1

J'ai une configuration assez simple. Pour résumer, voici ce que je fais:: problème de relation has_one lors de l'utilisation de MongoDB

class Movie 
    include MongoMapper::Document 
    has_one :setting 
end 

class Setting 
    include MongoMapper::EmbeddedDocument 
    belongs_to :movie 
end 

Ce que je veux faire est de mettre à jour le cadre d'un film dans la même forme que le film d'autres informations. À cet effet, je le fais:

- form_for ['movies', @movie] do |f| 
    # ... 
    -f.fields_for @movie.setting do |ms| 
    # ... 

Cela ne fonctionne pas comme je reçois cette erreur:

stack level too deep 

[ci-dessous texte est répété cent fois ou si]

/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/associations/one_proxy.rb:46:in `find_target' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/associations/proxy.rb:98:in `load_target' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/associations/proxy.rb:88:in `method_missing' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/associations/one_proxy.rb:56:in `target_class' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/associations/one_proxy.rb:46:in `find_target' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/associations/proxy.rb:98:in `load_target' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/associations/one_proxy.rb:17:in `replace' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/associations.rb:39:in `setting=' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/embedded_document.rb:185:in `send' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/embedded_document.rb:185:in `initialize' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/embedded_document.rb:177:in `each' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/embedded_document.rb:177:in `initialize' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/dirty.rb:42:in `initialize' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/embedded_document.rb:91:in `new' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/embedded_document.rb:91:in `initialize_doc' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/document.rb:316:in `find_one' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/document.rb:321:in `find_one!' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/document.rb:88:in `find!' 
/Users/marc/.gem/ruby/1.8/gems/mongo_mapper-0.6.10/lib/mongo_mapper/document.rb:96:in `find' 
/Users/marc/Code/mycompany/dontreadthat/sources/app/controllers/application_controller.rb:53:in `set_page_title' 

Voici la capture: Lorsque je remplace la relation has_one par une clé dans le modèle Movie:

key :setting, Setting 

... cela fonctionne bien. Aucune erreur de pile.

je pouvais laisser tomber la relation et aller avec la clé, mais:

  • Ce n'est pas assez

  • Si je tente de mettre à jour en utilisant movie.setting .update_attributes il supprime tous les autres attributs. Disons que je mets à jour movie.setting.key1, il réinitialise movie.setting.key2 ... ce qui est normal

Je ne peux pas trouver quelque chose d'utile là-bas, de sorte que toute aide ou pointeurs seraient grandement appréciés .

Répondre

0

j'ai fini par mettre le réglage comme une clé et une surcharge de la = méthode:

dans le film

def setting=(new_setting) 
    super ((self.setting.nil?)? new_setting : (self.setting.keys.merge new_setting)) 
    end 

et dans la mise

def keys 
    keys_hash = {} 
    self.attributes.each do |attribute| 
     keys_hash.merge!({attribute[0].to_s => attribute[1].to_s}) unless attribute[0].to_s == "_id" 
    end 
    return keys_hash 
    end 

Ce n'est pas optimale, mais ça va fonctionne bien jusqu'à ce qu'il y ait une meilleure façon de faire has_one relations.

3

Je suis pratiquement sûr que les relations has_one ne sont pas supportées en tant que documents incorporés. Ainsi, par exemple, ce fait travail:

class Setting 
    include MongoMapper::Document 
    key :movie_id, ObjectId 
    belongs_to :movie 
end 

class Movie 
    include MongoMapper::Document 
    one :setting, :class => Setting 
end 

Si vous ne voulez pas la première classe Paramètres du document, que vous n'avez probablement pas besoin, vous pourriez envisager de stocker ces paramètres à l'aide d'une clé de type Hash ou une autre clé de type personnalisé que vous avez définie pour Mongo. Voir la classe WindowSize dans la suite de tests MongoMapper pour un exemple.

+0

Merci pour la réponse. J'ai toujours mon problème: si je le fais de cette façon, chaque fois que j'essaie d'accéder à @ movie.setting, j'obtiens une "méthode non définie" en premier pour "Setting: Class" error ... – marcgg