我的设置非常简单。总结一下,这就是我正在做的事情:
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 :(得分: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
如果您不想要您可能不需要的第一类设置文档,可以考虑使用Hash类型的键或您为Mongo定义的某个自定义类型的其他键来存储这些设置。有关示例,请参阅MongoMapper测试套件中的WindowSize类。
答案 1 :(得分: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
这不是最优的,但是在有更好的方式进行has_one关系之前它会正常工作。