繁体   English   中英

:使用MongoDB时的has_one关系问题

[英]:has_one relationship problem when using MongoDB

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

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

我找不到任何有帮助的东西,因此将不胜感激任何帮助或指针。

我敢肯定,嵌入式文档不支持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类。

我最终将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关系之前,它会很好地工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM