0

我有一个非常奇怪的问题。

这是堆栈:

  • Mongoid 3.0.0
  • Rails 3.2.11 堆栈
  • mongoid_token ~> 1.1.0
  • MongoDB 2.2.0.

我运行了 rake 命令rake db:mongoid:create_indexes,看起来索引都是这样创建的:

MONGOID: Created indexes on Mongoid::GridFS::Fs::Chunk:
MONGOID: Index: {:files_id=>1, :n=>-1}, Options: {:unique=>true}
MONGOID: Created indexes on Mongoid::GridFS::Fs::File:
MONGOID: Index: {:filename=>1}, Options: {:unique=>true}
...
...
MONGOID: Created indexes on User:
MONGOID: Index: {:token=>1}, Options: {:unique=>true}
...

然后我创建一个用户:

u = User.create!(params)
u.persisted?
 => true

如果我然后使用mongo外壳,我可以清楚地看到没有任何东西被持久化。同样, User.count 也不会返回正确的数字。

我错过了什么?

4

1 回答 1

2

我发现了问题。这更多地与一个陷阱有关,所以我想我会发布它以防万一其他人有类似的问题。原来这是我使用 Mongoid 的方式。

我有一个这样的基类:

class PersistentModel
  include Mongoid::Document
  ..
  # Common class and instance methods that I need across any persistent model
  ..
end

class User < PersistentModel
  # User methods
end

事实证明,这可以正常工作,因为您不会注意到 Ruby 端的任何故障。一切都会坚持下去。

但是,如果您在 mongodb 端进行挖掘,您会发现所有内容都保存在 persistent_models 集合中,鉴于存在单独的用户模型,这不是您所期望的。它还会对您的索引造成严重破坏,因为所有索引都是针对一个集合生成的,从而导致冲突和问题(即另一个症状是 rake db:mongoid:create_indexes 命令将报告在没有的模型上创建的多个索引在这些字段上指定的任何索引)。

解决方案是这样做...

module PersistentModel
  def self.included(base)
    base.instance_eval do
      include Mongoid::Document
      ..
      # Common class and instance methods that I need across any persistent model
      ..          
    end
  end
end

class User
  include PersistentModel
  ..
end

这样,您仍然可以在任何 mongoid 模型中放置您可能需要的“通用”方法,并且 Mongoid::Document 混合到真正的模型类中,在 mongodb 端生成正确的集合。

方便的故障排除技巧

这些是一些提示,如果我早点知道的话,会为我节省一些时间……

  1. 将您的 mongoid.yml 配置文件中的安全模式设置为 true
    • 我没有打开它,这就是保存成功的原因,即使存在潜在错误。错误是无法生成索引,因为该值为 nil。
  2. 使用 mongo shell 并查看持续存在的 mongoid
  3. 检查您的 mongoid 正在生成的索引
于 2013-02-27T22:40:55.853 回答