I'm building a REST api for this project that uses Mongoid.
I've setup the following to catch the Mongoid::Errors::DocumentNotFound
exception:
rescue_from Mongoid::Errors::DocumentNotFound in my base controller
In my controller I've this query code:
@current_account.users.find(:first, :conditions => {:name => "some_name"})
The above query just returns nil
. It doesn't raise the exception.
Tried with another syntax as well:
User.find(:conditions => {:name => "same"}).first
All those methods just runs where
internally and afaik where
doesn't raise exception, its simply returns []
So what can be the solution to this? I want partially dynamic finder but should raise the exception too?
I've met same problem today, and found another solution.
Set raise_not_found_error
to false
. so your config/mongoid.yml should be
development:
host: localhost
port: 10045
username: ...
password: ...
database: ...
raise_not_found_error: false
from http://mongoid.org/docs/installation/configuration.html
I believe that Mongoid will only raise a DocumentNotFound
exception when using the find
method by passing in an object's id (and not with conditions). Otherwise it will return nil. From the Mongoid source:
# 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.
You will have to check manually to see if you got any results and either raise the DocumentNotFound exception yourself (not great), or raise your own custom exception (better solution).
An example of the former would be something like this:
raise Mongoid::Errors::DocumentNotFound.new(User, params[:name]) unless @current_account.users.first(:conditions => {:name => params[:name]})
Update: I haven't tested any of this, but it should allow you to make calls like (or at least point you in the right direction - i hope!):
@current_account.users.where!(:conditions => {:name => params[:name]})
Which will throw a custom Mongoid::CollectionEmpty
error, if the collection returned from the query is empty. Note that it's not the most efficient solution, since in order to find out if the returned collection is empty - it has to actually process the query.
Then all you need to do is rescue from Mongoid::CollectionEmpty
instead (or as well).
# 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With