我正在为使用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
不会引发异常,它只返回[]
那么解决这个问题的方法是什么?我想要部分动态查找器但是也应该引发异常吗?
答案 0 :(得分:6)
我今天遇到了同样的问题,并找到了另一种解决方案。
将raise_not_found_error
设为false
。所以你的config / mongoid.yml应该是
development:
host: localhost
port: 10045
username: ...
password: ...
database: ...
raise_not_found_error: false
答案 1 :(得分:3)
我相信Mongoid只会在使用DocumentNotFound
方法时通过传入对象的id(而不是条件)来引发find
异常。否则它将返回零。来自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