modify search behavior - require 3 characters, remove description searches to description: filter, consider items with no species support IDs to support all

This commit is contained in:
Emi Matchu 2010-05-15 14:56:21 -04:00
parent 4497c6bbdb
commit 80b1bf7c61
2 changed files with 33 additions and 25 deletions

View file

@ -19,8 +19,9 @@ class Item < ActiveRecord::Base
end end
def self.search(query) def self.search(query)
query = query.strip if query raise ArgumentError, "Please provide a search query" unless query
raise ArgumentError, "Please provide a search query" if query.blank? query = query.strip
raise ArgumentError, "Search queries should be at least 3 characters" if query.length < 3
query_conditions = [Condition.new] query_conditions = [Condition.new]
in_phrase = false in_phrase = false
query.each_char do |c| query.each_char do |c|
@ -58,17 +59,16 @@ class Item < ActiveRecord::Base
if @property == 'species' if @property == 'species'
species = Species.find_by_name(self) species = Species.find_by_name(self)
# TODO: add a many-to-many table to handle this relationship # TODO: add a many-to-many table to handle this relationship
condition = items[:species_support_ids].matches_any( ids = items[:species_support_ids]
condition = ids.eq('').or(ids.matches_any(
species.id, species.id,
"#{species.id},%", "#{species.id},%",
"%,#{species.id},%", "%,#{species.id},%",
"%,#{species.id}" "%,#{species.id}"
) ))
else else
matcher = "%#{self}%" column = @property ? @property : :name
condition = items[:name].matches(matcher).or( condition = items[column].matches("%#{self}%")
items[:description].matches(matcher)
)
end end
condition = condition.not if @negative condition = condition.not if @negative
scope.where(condition) scope.where(condition)

View file

@ -72,18 +72,17 @@ describe Item do
] ]
end end
specify "should search name and description" do specify "should search description for words and phrases" do
query_should 'zero "one two"', query_should 'description:zero description:"one two"',
:return => [ :return => [
'zero one two', ['Green Hat', 'zero one two three'],
['zero one', 'one two three'], ['Blue Hat', 'five one two four zero']
['one two four', 'one three zero'],
['three', 'one two four zero']
], ],
:not_return => [ :not_return => [
['zero one', 'two'], 'Zero one two',
['one two four', 'three'], ['Zero one', 'two'],
['five two', 'zero one three two'] ['Zero', 'One two'],
['Three', 'One zero two']
] ]
end end
@ -106,20 +105,28 @@ describe Item do
Item.search('red species:aisha').count.should == 1 Item.search('red species:aisha').count.should == 1
end end
specify "should return items with no species requirements if a species condition is added" do
Factory.create :item, :species_support_ids => [1]
Factory.create :item, :species_support_ids => [1,2]
Factory.create :item, :species_support_ids => []
Item.search('species:acara').count.should == 3
Item.search('species:aisha').count.should == 2
Item.search('species:acara species:aisha').count.should == 2
Item.search('-species:acara').count.should == 0
Item.search('-species:aisha').count.should == 1
end
specify "should be able to negate word in search" do specify "should be able to negate word in search" do
query_should 'hat -blue', query_should 'hat -blue',
:return => [ :return => [
'Green Hat', 'Green Hat',
'Red Hat', 'Red Hat',
'Blu E Hat', 'Blu E Hat',
['Yellow Hat', 'This hat is not green!']
], ],
:not_return => [ :not_return => [
'Blue Hat', 'Blue Hat',
'Green Shirt', 'Green Shirt',
'Blue Shirt', 'Blue Shirt',
['Orange Hat', 'This hat is not blue!'],
['Blue Pants', 'This is not a hat!']
] ]
end end
@ -138,23 +145,24 @@ describe Item do
query_should 'zero -"one two"', query_should 'zero -"one two"',
:return => [ :return => [
'Zero two one', 'Zero two one',
['Two one', 'Zero'],
'One three two zero' 'One three two zero'
], ],
:not_return => [ :not_return => [
'Zero one two', 'Zero one two',
['Zero', 'one two three'], 'One two three zero'
['One two four', 'Zero one']
] ]
end end
specify "should return raise exception for a query with no conditions" do specify "should raise exception for a query with no conditions" do
Factory.create :item
[ [
lambda { Item.search('').all }, lambda { Item.search('').all },
lambda { Item.search(nil).all }, lambda { Item.search(nil).all },
lambda { Item.search(' ').all } lambda { Item.search(' ').all }
].each { |l| l.should raise_error(ArgumentError) } ].each { |l| l.should raise_error(ArgumentError) }
end end
specify "should raise exception for a query that's too short" do
lambda { Item.search('e').all }.should raise_error(ArgumentError)
end
end end
end end