Mongoid 在 ruby​​ 1.9.3 上失败

Posted

技术标签:

【中文标题】Mongoid 在 ruby​​ 1.9.3 上失败【英文标题】:Mongoid fails on ruby 1.9.3 【发布时间】:2012-11-09 15:35:27 【问题描述】:

所以我在玩 mongo 的东西。创建了一个新的 heroku 应用程序,为其添加了一个 mongolab 选项,但是每个 mongoid 方法都失败了。

我用谷歌搜索了一下,看起来这个问题在 1.9.3 之前的 ruby​​ 中很常见,但我运行的是 1.9.3。

这是最简单的失败示例:

require 'sinatra'
require 'mongoid'
require 'json'
require "sinatra/reloader" if development?

Mongoid.load!("mongoid.yml")

class Company
    include Mongoid::Document

    field :code, type: String
    field :sector, type: String
    field :share_id, type: Integer
    field :jse_code, type: Integer
end

get '/' do
    "Hello" 
end

get '/company' do
    Company.exists?
end

无论我在本地(针对 mongolab db)还是在 heroku 上运行它,我都会遇到同样的错误:

12:22:33 web.1  | NoMethodError - undefined method `match' for nil:NilClass:
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/sessions/mongo_uri.rb:49:in `initialize'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/sessions/factory.rb:103:in `new'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/sessions/factory.rb:103:in `parse'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/sessions/factory.rb:62:in `create_session'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/sessions/factory.rb:43:in `default'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/sessions.rb:109:in `default'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/sessions.rb:378:in `__session__'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/sessions.rb:213:in `mongo_session'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/sessions.rb:157:in `collection'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/contextual/mongo.rb:216:in `initialize'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/contextual.rb:47:in `new'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/contextual.rb:47:in `create_context'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/contextual.rb:30:in `context'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/contextual.rb:20:in `rescue in exists?'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/contextual.rb:18:in `exists?'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/mongoid-3.0.13/lib/mongoid/finders.rb:43:in `exists?'
12:22:33 web.1  |   app.rb:22:in `block in <main>'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:1265:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:1265:in `block in compile!'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:835:in `[]'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:835:in `block (3 levels) in route!'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:851:in `route_eval'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:835:in `block (2 levels) in route!'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:872:in `block in process_route'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:870:in `catch'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:870:in `process_route'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:834:in `block in route!'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:833:in `each'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:833:in `route!'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:936:in `dispatch!'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:769:in `block in call!'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:921:in `block in invoke'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:921:in `catch'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:921:in `invoke'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:769:in `call!'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:755:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/rack-protection-1.2.0/lib/rack/protection/xss_header.rb:22:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/rack-protection-1.2.0/lib/rack/protection/path_traversal.rb:16:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/rack-protection-1.2.0/lib/rack/protection/json_csrf.rb:17:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/rack-protection-1.2.0/lib/rack/protection/base.rb:47:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/rack-protection-1.2.0/lib/rack/protection/xss_header.rb:22:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.4.1/lib/rack/logger.rb:15:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.4.1/lib/rack/commonlogger.rb:20:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:136:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:129:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.4.1/lib/rack/head.rb:9:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.4.1/lib/rack/methodoverride.rb:21:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/showexceptions.rb:21:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:99:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:1389:in `block in call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:1471:in `synchronize'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/sinatra-1.3.3/lib/sinatra/base.rb:1389:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:81:in `block in pre_process'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:79:in `catch'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:79:in `pre_process'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/eventmachine-1.0.0/lib/eventmachine.rb:1037:in `call'
12:22:33 web.1  |   /Users/sdx/.rvm/gems/ruby-1.9.3-p327/gems/eventmachine-1.0.0/lib/eventmachine.rb:1037:in `block in spawn_threadpool'
12:22:33 web.1  | 127.0.0.1 - - [21/Nov/2012 12:22:33] "GET /__sinatra__/500.png HTTP/1.1" 200 31056 0.0062

我做错了什么?

更新这是我的 mongoid.yml:

production:
    sessions:
        default:
            uri: <%= ENV['MONGOLAB_URI'] %>
            options:
                skip_version_check: true
                safe: true
development:
    sessions:
        default:
            uri: <%= ENV['MONGOLAB_URI'] %>

【问题讨论】:

【参考方案1】:

根据堆栈跟踪,mongo_uri 的构造函数似乎被传递了一个空值。我会在您的mongoid.yml 中检查以下内容:

它在正确的位置/load! 的参数指向正确的位置 配置正确 如果它引用了在您的环境中设置的任何环境变量(例如,MONGOLAB_URI 用于 MongoLab Heroku 插件)

来自mongo_uri.rb:49 的相关行,其中抛出异常:

  # Create the new uri from the provided string.
  #
  # @example Create the new uri.
  #   MongoUri.new(uri)
  #
  # @param [ String ] string The uri string.
  #
  # @since 3.0.0
  def initialize(string)
    @match = string.match(URI)
  end

【讨论】:

我用我的 mongoid.yml 文件更新了这个问题。我很确定它会读取它,因为它会抱怨,例如没有默认值,或者 env 变量是否错误 所以你是对的,在本地这是一个连接问题。在服务器上,尽管我的 Gemfile 说了什么,它使用的是 1.9.1。因此,两个不同的问题导致了完全的混乱。【参考方案2】:

这与heroku在编译资产时不使用环境变量有关。

使用 heroku 的这个实验室功能将有助于解决这个问题:https://devcenter.heroku.com/articles/labs-user-env-compile

【讨论】:

以上是关于Mongoid 在 ruby​​ 1.9.3 上失败的主要内容,如果未能解决你的问题,请参考以下文章

Ruby on Rails 是 mongodb - mongoid

使用 Mongoid 和 Ruby 查询最近 30 天的日期范围?

ruby Mongoid数据库可缓存

ruby mongoid_document.rb

ruby mongoid存储架会话Rack :: Session :: RackAndMongo

如何使用 Ruby Geocoder/Mongoid 查询某个点附近的对象?