1

我有一个非常简单的设置。总结一下,这就是我正在做的事情:

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 ...这是正常的

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

4

2 回答 2

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 类。

于 2010-01-21T18:23:14.980 回答
0

我最终将 Setting 设置为键并重载 = 方法:

在电影中

  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 关系之前它会正常工作。

于 2010-01-22T13:06:35.770 回答