Skip to content
This repository has been archived by the owner on Sep 27, 2022. It is now read-only.

Commit

Permalink
Do not raise on missing objects.
Browse files Browse the repository at this point in the history
The use of ActiveRecord's #find meant missing IDs raised AR::RecordNotFound. This might come up if an object was created and then deleted without its trigram data also being deleted. To avoid the exception this uses #where instead of #find which will ignore missing results.

Due to the method with which the records are sorted to match the trigram query, in these cases nils were cropping up in the results, so this uses #compact to just return the records.

The first test case ensures no exceptions are raised. The second test case ensures the fuzzy find still works and that no nils are returned.
  • Loading branch information
savef committed Aug 25, 2015
1 parent e373a70 commit 4ccbab8
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 5 deletions.
6 changes: 3 additions & 3 deletions lib/fuzzily/searchable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ def _find_by_fuzzy(_o, pattern, options={})
matches_for(pattern)
records = _load_for_ids(trigrams.map(&:owner_id))
# order records as per trigram query (no portable way to do this in SQL)
trigrams.map { |t| records[t.owner_id] }
trigrams.map { |t| records[t.owner_id] }.compact
end

def _load_for_ids(ids)
{}.tap do |result|
find(ids).each { |_r| result[_r.id] = _r }
where(:id => ids).each { |_r| result[_r.id] = _r }
end
end

Expand Down Expand Up @@ -136,7 +136,7 @@ def make_field_fuzzily_searchable(field, options={})

after_save do |record|
next unless record.send("#{field}_changed?".to_sym)

record.send(_o.update_trigrams_method)
end

Expand Down
18 changes: 16 additions & 2 deletions spec/fuzzily/searchable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
before(:each) { prepare_trigrams_table }
before(:each) { prepare_owners_table }

subject do
subject do
silence_warnings do
Stuff = Class.new(ActiveRecord::Base)
end
Expand Down Expand Up @@ -73,7 +73,7 @@ def Stuff.name ; 'Stuff' ; end
before do
subject.fuzzily_searchable :name
end

it 're-creates trigrams' do
subject.create!(:name => 'Paris')
old_ids = Trigram.all.map(&:id)
Expand Down Expand Up @@ -171,6 +171,20 @@ def Stuff.name ; 'Stuff' ; end
3.times { subject.create!(:name => 'Paris') }
subject.find_by_fuzzy_name('Paris', :offset => 2).length.should == 1
end

it 'does not raise on missing objects' do
subject.fuzzily_searchable :name
belgium = subject.create(:name => 'Belgium')
belgium.delete
subject.find_by_fuzzy_name('Belgium')
end

it 'finds others alongside missing' do
subject.fuzzily_searchable :name
belgium1, belgium2 = 2.times.map { subject.create(:name => 'Belgium') }
belgium1.delete
subject.find_by_fuzzy_name('Belgium').should == [belgium2]
end
end
end

Expand Down

0 comments on commit 4ccbab8

Please sign in to comment.