2010-01-21 88 views
1

我有一个非常简单的设置。在这里概括起来是我在做什么::使用MongoDB时has_one的关系问题

class Movie 
    include MongoMapper::Document 
    has_one :setting 
end 

class Setting 
    include MongoMapper::EmbeddedDocument 
    belongs_to :movie 
end 

我想要做的是在相同的形式电影等信息来更新电影的设置。为此我做:

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

,因为我得到这个错误这不起作用:

stack level too deep 

[文字波纹管重复百倍左右]

/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' 

这里有一个问题:当我用Movie模型中的一个键替换has_one关系时:

key :setting, Setting 

...它工作正常。没有堆栈错误。

我可能只是下降的关系,并与关键,但去:

  • 如果我尝试更新使用.update_attributes它丢弃所有其他属性movie.setting这不是漂亮

  • 。比方说,我更新movie.setting.key1,它会重置movie.setting.key2 ...这是正常的

我找不到任何有用的摆在那里,所以任何帮助或指针将不胜感激。

回答

0

我结束了设定的设定作为重点和重载=方法:

在电影

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

,并在制定

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 

这不是最佳,但它会工作得很好,直到有更好的方式去做一对一的关系。

3

我很确定has_one关系不支持作为嵌入式文档。因此,举例来说,这确实工作

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

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

如果你不想一流的设置文件,你可能不需要,你可能会考虑使用存储类型的密钥这些设置散列或您为Mongo定义的某种自定义类型的其他键。以MongoMapper测试套件中的WindowSize类为例。

+0

感谢您的回答。我仍然有我的问题:如果我这样做,每次我尝试访问@ movie.setting我得到一个“未定义的方法”第一个'设置:类“错误... – marcgg 2010-01-22 08:25:23