2011-07-12 54 views
5

我正在爲使用Mongoid的這個項目構建一個REST API。用Mongoid :: Errors :: DocumentNotFound異常引發的Mongoid動態查找器

我設置以下搭上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不會引發例外,它只是返回[]

那麼什麼可以解決這個?我想要部分動態查找器,但也應該引發異常?

回答

3

我相信Mongoid只會通過傳遞一個對象的id(而不是條件)來使用find方法時引發一個DocumentNotFound異常。否則它將返回零。從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 
+0

是啊,那是相當長和重複每次都寫。我可能會寫一個寶石來處理這個。但由於時間的限制,我會繼續研究這個問題。謝謝。 – Autodidact

+0

我有更多時間在我的手上,我爲Mongoid添加了一個快速的猴子補丁解決方案,它增加了自定義標準方法和一個自定義的EmptyCollection錯誤。希望這會讓事情變得更易於管理! :) – theTRON

+0

這是錯誤:'失敗/錯誤:得到「#{url} /#{account.name} /non-existing.json」,::api_key => application.key undefined method expand_complex_criteria'for [{ :conditions => {:title =>「non-existing」}}]:Array #./lib/mongoid_criterion_with_errors.rb:8:in where!' – Autodidact