How to chain optional Mongoid criteria in separate statements?
I'm trying to chain criteria based on optional rails parameters.
I want to be able to simultaneously filter based on selected tags as well as searching.
Here is the current code that works in all situations:
if params[:tag] and params[:search]
@notes = Note.tagged_with_criteria(params[:tag]).full_text_search(params[:search])
elsif params[:tag]
@notes = Note.tagged_with_criteria(params[:tag])
elsif params[:search]
@notes = Note.full_text_search(params[:search])
end
I tried simply using
@notes = Note.tagged_with_criteria(params[:tag]).full_text_search(params[:search])
without the if statement, but then if only one of the params was given, then all notes are returned.
Each of the methods (tagged_with_criteria and full_text_search) are returning Note.criteria if their parameter is nil / empty.
Is there a simpler, more elegant way to chain Mon开发者_JAVA百科goid criteria like this?
I'd rather keep tacking on criteria one-by-one instead of having to do the weird "if params[...] and params[...]" thing..
UPDATE: here are the current methods:
def tagged_with_criteria(_tags)
_tags = [_tags] unless _tags.is_a? Array
if _tags.empty?
criteria
else
criteria.in(:tags => _tags)
end
end
def self.full_text_search(query)
if query
begin
regex = /#{query}/
# supplied string is valid regex (without the forward slashes) - use it as such
criteria.where(:content => regex)
rescue
# not a valid regexp -treat as literal search string
criteria.where(:content => (/#{Regexp.escape(query)}/))
end
else
# show all notes if there's no search parameter
criteria
end
end
In a situation like that, I would modify the scopes to do nothing when passed in blank values.
I think what might be happening is you are getting empty strings from the params hash, which is causing your code to think that something was entered. Try the scopes with these edits.
def tagged_with_criteria(_tags)
_tags = Array.wrap(_tags).reject(&:blank?)
if _tags.empty?
criteria
else
criteria.in(:tags => _tags)
end
end
def self.full_text_search(query)
if query.present?
begin
regex = /#{query}/
# supplied string is valid regex (without the forward slashes) - use it as such
criteria.where(:content => regex)
rescue
# not a valid regexp -treat as literal search string
criteria.where(:content => (/#{Regexp.escape(query)}/))
end
else
# show all notes if there's no search parameter
criteria
end
end
精彩评论