我正在为这个使用Mongoid的项目构建一个REST api。
我已经设置了以下内容来捕获Mongoid::Errors::DocumentNotFound异常:
rescue_from Mongoid::Errors::DocumentNotFound in my base controller在我的控制器中,我有这样的查询代码:
@current_account.users.find(:first, :conditions => {:name => "some_name"})上面的查询只返回nil。它不会引发异常。也尝试了另一种语法:
User.find(:conditions => {:name => "same"}).first所有这些方法都只是在内部运行where,并且afaik where不会引发异常,它只是返回[]
那么解决这个问题的办法是什么呢?我想要部分动态的查找器,但也应该引发异常吗?
发布于 2011-07-12 18:11:50
我相信只有在使用find方法时,Mongoid才会通过传入对象的id (而不是带条件)来引发DocumentNotFound异常。否则,它将返回nil。来自Mongoid源码:
# lib/mongoid/errors/document_not_found.rb
# Raised when querying the database for a document by a specific id which
# does not exist. If multiple ids were passed then it will display all of
# those.您必须手动检查是否获得了任何结果,然后自己引发DocumentNotFound异常(不是很好),或者引发您自己的自定义异常(更好的解决方案)。
前者的示例如下所示:
raise Mongoid::Errors::DocumentNotFound.new(User, params[:name]) unless @current_account.users.first(:conditions => {:name => params[:name]})更新:我还没有测试过这些,但是它应该允许你这样调用(或者至少给你指出正确的方向-我希望!):
@current_account.users.where!(:conditions => {:name => params[:name]})如果查询返回的集合为空,将抛出自定义Mongoid::CollectionEmpty错误。请注意,这不是最有效的解决方案,因为为了找出返回的集合是否为空-它必须实际处理查询。
那么你需要做的就是从Mongoid::CollectionEmpty中解救出来(或者也是)。
# lib/mongoid_criterion_with_errors.rb
module Mongoid
  module Criterion
    module WithErrors
      extend ActiveSupport::Concern
      module ClassMethods
        def where!(*args)
          criteria = self.where(args)
          raise Mongoid::EmptyCollection(criteria) if criteria.empty?
          criteria
        end
      end
    end
  end
  class EmptyCollection < StandardError
    def initialize(criteria)
      @class_name = criteria.class
      @selector = criteria.selector
    end
    def to_s
      "Empty collection found for #{@class_name}, using selector: #{@selector}"
    end
  end
end
# config/application.rb
module ApplicationName
  class Application < Rails::Application
    require 'mongoid_criterion_with_errors'
    #...snip...
  end
end
# app/models/user.rb
class User
  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Criterion::WithErrors
  #...snip...
end发布于 2011-08-11 19:04:52
我今天遇到了同样的问题,并找到了另一个解决方案。
将raise_not_found_error设置为false。所以你的config/mongoid.yml应该是
development:
  host: localhost
  port: 10045
  username: ...
  password: ...
  database: ...
  raise_not_found_error: false来自http://mongoid.org/docs/installation/configuration.html
https://stackoverflow.com/questions/6661858
复制相似问题